Skip to content

Commit

Permalink
chore(toolkit): programmatic toolkit for the AWS CDK initial code (#3…
Browse files Browse the repository at this point in the history
…2919)

### Description of changes

Initial code for the Programmatic Toolkit. This won't be released just yet.
Contains a mix of extensions and hard copies to the current CLI code.
After this PR we are moving the appropriate tests over from the CLI.

### Describe any new or updated permissions being added

n/a

### Description of how you validated changes

For the changes to `aws-cdk` we run the existing tests and the integration tests.

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
mrgrain authored Jan 16, 2025
1 parent d68020b commit 35275c3
Show file tree
Hide file tree
Showing 42 changed files with 2,587 additions and 187 deletions.
22 changes: 21 additions & 1 deletion packages/@aws-cdk/aws-custom-resource-sdk-adapter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,27 @@
"devDependencies": {
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@aws-sdk/client-account": "3.632.0",
"@aws-sdk/client-acm": "3.632.0",
"@aws-sdk/client-amplify": "3.632.0",
"@aws-sdk/client-cloudwatch": "3.632.0",
"@aws-sdk/client-cloudwatch-logs": "3.632.0",
"@aws-sdk/client-codepipeline": "3.632.0",
"@aws-sdk/client-dynamodb": "3.632.0",
"@aws-sdk/client-ec2": "3.632.0",
"@aws-sdk/client-ecr": "3.632.0",
"@aws-sdk/client-ecs": "3.632.0",
"@aws-sdk/client-eks": "3.632.0",
"@aws-sdk/client-kinesis": "3.632.0",
"@aws-sdk/client-kms": "3.632.0",
"@aws-sdk/client-lambda": "3.632.0",
"@aws-sdk/client-redshift": "3.632.0",
"@aws-sdk/client-route-53": "3.632.0",
"@aws-sdk/client-s3": "3.632.0",
"@aws-sdk/client-ssm": "3.632.0",
"@aws-sdk/client-sts": "3.632.0",
"@aws-sdk/client-synthetics": "3.632.0",
"@aws-sdk/s3-request-presigner": "3.632.0",
"@smithy/types": "3.6.0",
"@types/jest": "^29.5.14",
"jest": "^29.7.0"
Expand All @@ -51,4 +71,4 @@
"publishConfig": {
"tag": "latest"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface AwsApiInput {
readonly service: string;
readonly action: string;
readonly parameters?: {
[param: string]: any,
[param: string]: any;
};
readonly apiVersion?: string;
readonly catchErrorPattern?: string;
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/toolkit/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*.js
*.js.map
*.d.ts
*.d.ts.map
*.gz
node_modules
dist
Expand Down
29 changes: 19 additions & 10 deletions packages/@aws-cdk/toolkit/.npmignore
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
# Ignore artifacts
# Ignore build artifacts
**/cdk.out
**/*.snapshot
dist
.LAST_PACKAGE
.LAST_BUILD
*.snk
*.ts
!*.d.ts
!*.js
coverage
.nyc_output
*.tgz

# Ignore configs and test files
# Ignore config files
.eslintrc.js
tsconfig.json
*.tsbuildinfo
junit.xml
jest.config.js
bundle.mjs

# Include .jsii
!.jsii

# exclude cdk artifacts
**/cdk.out
**/*.snapshot
# Explicitly allow all required files
!build-info.json
!db.json.gz
# !lib/main.js
# !lib/bridge.js
# !lib/setup-sandbox.js
# !lib/api/bootstrap/bootstrap-template.yaml
!*.d.ts
!*.d.ts.map
!*.js
!LICENSE
!NOTICE
!THIRD_PARTY_LICENSES
44 changes: 44 additions & 0 deletions packages/@aws-cdk/toolkit/bundle.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { createRequire } from 'node:module';
import * as path from "node:path";
import * as esbuild from "esbuild";
import * as fs from "fs-extra";

const require = createRequire(import.meta.url);

const cliPackage = path.dirname(require.resolve("aws-cdk/package.json"));
let copyFromCli = (from, to = undefined) => {
return fs.copy(path.join(cliPackage, ...from), path.join(process.cwd(), ...(to ?? from)))
}

await Promise.all([
copyFromCli(["build-info.json"]),
copyFromCli(["/db.json.gz"]),
copyFromCli(["lib", "index_bg.wasm"]),
])

// # Copy all resources that aws_cdk/generate.sh produced, and some othersCall the generator for the
// cp -R $aws_cdk/lib/init-templates ./lib/
// mkdir -p ./lib/api/bootstrap/ && cp $aws_cdk/lib/api/bootstrap/bootstrap-template.yaml ./lib/api/bootstrap/


let bundleCli = {
name: "bundle-aws-cdk",
setup(build) {

// Mark all paths inside aws-cdk as internal
build.onResolve({ filter: /^aws-cdk\/lib/ }, (args) => {
return { path: require.resolve(args.path), external: false }
});
},
};

await esbuild.build({
entryPoints: ["lib/index.ts"],
target: "node18",
platform: "node",
packages: "external",
plugins: [bundleCli],
sourcemap: true,
bundle: true,
outfile: "lib/main.js",
});
52 changes: 51 additions & 1 deletion packages/@aws-cdk/toolkit/lib/actions/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { StackSelector } from '../types';
import { Deployments, StackActivityProgress, WorkGraph } from '../api/aws-cdk';
import { StackSelector } from '../api/cloud-assembly/stack-selector';

export type DeploymentMethod = DirectDeploymentMethod | ChangeSetDeploymentMethod;

Expand Down Expand Up @@ -113,6 +114,7 @@ export interface BaseDeployOptions {
readonly stacks: StackSelector;

/**
* @deprecated set on toolkit
* Name of the toolkit stack to use/deploy
*
* @default CDKToolkit
Expand All @@ -130,6 +132,7 @@ export interface BaseDeployOptions {
* Always deploy, even if templates are identical.
*
* @default false
* @deprecated
*/
readonly force?: boolean;

Expand Down Expand Up @@ -225,4 +228,51 @@ export interface DeployOptions extends BaseDeployOptions {
* @default AssetBuildTime.ALL_BEFORE_DEPLOY
*/
readonly assetBuildTime?: AssetBuildTime;

/**
* Change stack watcher output to CI mode.
*
* @deprecated Implement in IoHost instead
*/
readonly ci?: boolean;

/**
* Display mode for stack deployment progress.
*
* @deprecated Implement in IoHost instead
*/
readonly progress?: StackActivityProgress;
}

export function buildParameterMap(parameters?: Map<string, string | undefined>): { [name: string]: { [name: string]: string | undefined } } {
const parameterMap: {
[name: string]: { [name: string]: string | undefined };
} = {};
parameterMap['*'] = {};

const entries = parameters?.entries() ?? [];
for (const [key, value] of entries) {
const [stack, parameter] = key.split(':', 2) as [string, string | undefined];
if (!parameter) {
parameterMap['*'][stack] = value;
} else {
if (!parameterMap[stack]) {
parameterMap[stack] = {};
}
parameterMap[stack][parameter] = value;
}
}

return parameterMap;
}

/**
* Remove the asset publishing and building from the work graph for assets that are already in place
*/
export async function removePublishedAssets(graph: WorkGraph, deployments: Deployments, options: DeployOptions) {
await graph.removeUnnecessaryAssets(assetNode => deployments.isSingleAssetPublished(assetNode.assetManifest, assetNode.asset, {
stack: assetNode.parentStack,
roleArn: options.roleArn,
stackName: assetNode.parentStack.stackName,
}));
}
9 changes: 8 additions & 1 deletion packages/@aws-cdk/toolkit/lib/actions/destroy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { StackSelector } from '../types';
import { StackSelector } from '../api/cloud-assembly/stack-selector';

export interface DestroyOptions {
/**
Expand All @@ -10,4 +10,11 @@ export interface DestroyOptions {
* The arn of the IAM role to use
*/
readonly roleArn?: string;

/**
* Change stack watcher output to CI mode.
*
* @deprecated Implement in IoHost instead
*/
readonly ci?: boolean;
}
116 changes: 116 additions & 0 deletions packages/@aws-cdk/toolkit/lib/actions/diff.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { StackSelector } from '../api/cloud-assembly/stack-selector';

export interface CloudFormationDiffOptions {
/**
* Whether to run the diff against the template after the CloudFormation Transforms inside it have been executed
* (as opposed to the original template, the default, which contains the unprocessed Transforms).
*
* @default false
*/
readonly compareAgainstProcessedTemplate?: boolean;
}

export interface ChangeSetDiffOptions extends CloudFormationDiffOptions {
/**
* Enable falling back to template-based diff in case creating the changeset is not possible or results in an error.
*
* Should be used for stacks containing nested stacks or when change set permissions aren't available.
*
* @default true
*/
readonly fallbackToTemplate?: boolean;

/**
* Additional parameters for CloudFormation when creating a diff change set
*
* @default {}
*/
readonly parameters?: { [name: string]: string | undefined };
}

export class DiffMethod {
/**
* Use a changeset to compute the diff.
*
* This will create, analyze, and subsequently delete a changeset against the CloudFormation stack.
*/
public static ChangeSet(options: ChangeSetDiffOptions = {}) {
return new class extends DiffMethod {
public override readonly options: ChangeSetDiffOptions;
public constructor(opts: ChangeSetDiffOptions) {
super('change-set', opts);
this.options = opts;
}
}(options);
}

public static TemplateOnly(options: CloudFormationDiffOptions = {}) {
return new class extends DiffMethod {
public override readonly options: CloudFormationDiffOptions;
public constructor(opts: CloudFormationDiffOptions) {
super('template-only', opts);
this.options = opts;
}
}(options);
}

public static LocalFile(path: string) {
return new class extends DiffMethod {
public override readonly options: { path: string };
public constructor(opts: { path: string }) {
super('local-file', opts);
this.options = opts;
}
}({ path });
};

private constructor(
public readonly method: 'change-set' | 'template-only' | 'local-file',
public readonly options: ChangeSetDiffOptions | CloudFormationDiffOptions | { path: string },
) {}
}

export interface DiffOptions {
/**
* Select the stacks
*/
readonly stacks: StackSelector;

/**
* The mode to create a stack diff.
*
* Use changeset diff for the highest fidelity, including analyze resource replacements.
* In this mode, diff will use the deploy role instead of the lookup role.
*
* Use template-only diff for a faster, less accurate diff that doesn't require
* permissions to create a change-set.
*
* Use local-template diff for a fast, local-only diff that doesn't require
* any permissions or internet access.
*
* @default DiffMode.ChangeSet
*/
readonly method: DiffMethod;

/**
* Strict diff mode
* When enabled, this will not filter out AWS::CDK::Metadata resources, mangled non-ASCII characters, or the CheckBootstrapVersionRule.
*
* @default false
*/
readonly strict?: boolean;

/**
* How many lines of context to show in the diff
*
* @default 3
*/
readonly contextLines?: number;

/**
* Only include broadened security changes in the diff
*
* @default false
*/
readonly securityOnly?: boolean;
}
7 changes: 7 additions & 0 deletions packages/@aws-cdk/toolkit/lib/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './deploy';
export * from './destroy';
export * from './diff';
export * from './import';
export * from './list';
export * from './synth';
export * from './watch';
8 changes: 8 additions & 0 deletions packages/@aws-cdk/toolkit/lib/actions/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { StackSelector } from '../api/cloud-assembly/stack-selector';

export interface ListOptions {
/**
* Select the stacks
*/
readonly stacks: StackSelector;
}
Loading

0 comments on commit 35275c3

Please sign in to comment.