Skip to content

Commit

Permalink
chore(toolkit): add proposed initial interfaces (#32643)
Browse files Browse the repository at this point in the history
### Issue

Close #32567 

### Reason for this change

Add proposed interfaces and stub classes to the `@aws-cdk/toolkit` package according to RFC 300, so integrators can start designing their own solution.

### Describe any new or updated permissions being added

n/a

### Description of how you validated changes

n/a unused stub interfaces

### 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 Dec 24, 2024
1 parent fcf37ee commit dcf1d74
Show file tree
Hide file tree
Showing 12 changed files with 520 additions and 7 deletions.
228 changes: 228 additions & 0 deletions packages/@aws-cdk/toolkit/lib/actions/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
import { StackSelector } from '../types';

export type DeploymentMethod = DirectDeploymentMethod | ChangeSetDeploymentMethod;

export interface DirectDeploymentMethod {
/**
* Use stack APIs to the deploy stack changes
*/
readonly method: 'direct';
}

export interface ChangeSetDeploymentMethod {
/**
* Use change-set APIS to deploy a stack changes
*/
readonly method: 'change-set';

/**
* Whether to execute the changeset or leave it in review.
*
* @default true
*/
readonly execute?: boolean;

/**
* Optional name to use for the CloudFormation change set.
* If not provided, a name will be generated automatically.
*/
readonly changeSetName?: string;
}

/**
* When to build assets
*/
export enum AssetBuildTime {
/**
* Build all assets before deploying the first stack
*
* This is intended for expensive Docker image builds; so that if the Docker image build
* fails, no stacks are unnecessarily deployed (with the attendant wait time).
*/
ALL_BEFORE_DEPLOY = 'all-before-deploy',

/**
* Build assets just-in-time, before publishing
*/
JUST_IN_TIME = 'just-in-time',
}

export interface Tag {
readonly Key: string;
readonly Value: string;
}

export enum RequireApproval {
NEVER = 'never',
ANY_CHANGE = 'any-change',
BROADENING = 'broadening',
}

export enum HotswapMode {
/**
* Will fall back to CloudFormation when a non-hotswappable change is detected
*/
FALL_BACK = 'fall-back',

/**
* Will not fall back to CloudFormation when a non-hotswappable change is detected
*/
HOTSWAP_ONLY = 'hotswap-only',

/**
* Will not attempt to hotswap anything and instead go straight to CloudFormation
*/
FULL_DEPLOYMENT = 'full-deployment',
}

export class StackParameters {
/**
* Use only existing parameters on the stack.
*/
public static onlyExisting() {
return new StackParameters({}, true);
};

/**
* Use exactly these parameters and remove any other existing parameters from the stack.
*/
public static exactly(params: { [name: string]: string | undefined }) {
return new StackParameters(params, false);
};

/**
* Define additional parameters for the stack, while keeping existing parameters for unspecified values.
*/
public static withExisting(params: { [name: string]: string | undefined }) {
return new StackParameters(params, true);
};

public readonly parameters: Map<string, string | undefined>;
public readonly keepExistingParameters: boolean;

private constructor(params: { [name: string]: string | undefined }, usePreviousParameters = true) {
this.keepExistingParameters = usePreviousParameters;
this.parameters = new Map(Object.entries(params));
}
}

export interface BaseDeployOptions {
/**
* Criteria for selecting stacks to deploy
*/
readonly stacks: StackSelector;

/**
* Name of the toolkit stack to use/deploy
*
* @default CDKToolkit
*/
readonly toolkitStackName?: string;

/**
* Role to pass to CloudFormation for deployment
*/
readonly roleArn?: string;

/**
* @TODO can this be part of `DeploymentMethod`
*
* Always deploy, even if templates are identical.
*
* @default false
*/
readonly force?: boolean;

/**
* Deployment method
*/
readonly deploymentMethod?: DeploymentMethod;

/**
* @TODO can this be part of `DeploymentMethod`
*
* Whether to perform a 'hotswap' deployment.
* A 'hotswap' deployment will attempt to short-circuit CloudFormation
* and update the affected resources like Lambda functions directly.
*
* @default - `HotswapMode.FALL_BACK` for regular deployments, `HotswapMode.HOTSWAP_ONLY` for 'watch' deployments
*/
readonly hotswap: HotswapMode;

/**
* Rollback failed deployments
*
* @default true
*/
readonly rollback?: boolean;

/**
* Reuse the assets with the given asset IDs
*/
readonly reuseAssets?: string[];

/**
* Maximum number of simultaneous deployments (dependency permitting) to execute.
* The default is '1', which executes all deployments serially.
*
* @default 1
*/
readonly concurrency?: number;
}

export interface DeployOptions extends BaseDeployOptions {
/**
* ARNs of SNS topics that CloudFormation will notify with stack related events
*/
readonly notificationArns?: string[];

/**
* What kind of security changes require approval
*
* @default RequireApproval.Broadening
*/
readonly requireApproval?: RequireApproval;

/**
* Tags to pass to CloudFormation for deployment
*/
readonly tags?: Tag[];

/**
* Stack parameters for CloudFormation used at deploy time
* @default StackParameters.onlyExisting()
*/
readonly parameters?: StackParameters;

/**
* Path to file where stack outputs will be written after a successful deploy as JSON
* @default - Outputs are not written to any file
*/
readonly outputsFile?: string;

/**
* Whether to show logs from all CloudWatch log groups in the template
* locally in the users terminal
*
* @default - false
*/
readonly traceLogs?: boolean;

/**
* Build/publish assets for a single stack in parallel
*
* Independent of whether stacks are being done in parallel or no.
*
* @default true
*/
readonly assetParallelism?: boolean;

/**
* When to build assets
*
* The default is the Docker-friendly default.
*
* @default AssetBuildTime.ALL_BEFORE_DEPLOY
*/
readonly assetBuildTime?: AssetBuildTime;
}
13 changes: 13 additions & 0 deletions packages/@aws-cdk/toolkit/lib/actions/destroy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { StackSelector } from '../types';

export interface DestroyOptions {
/**
* Criteria for selecting stacks to deploy
*/
readonly stacks: StackSelector;

/**
* The arn of the IAM role to use
*/
readonly roleArn?: string;
}
24 changes: 24 additions & 0 deletions packages/@aws-cdk/toolkit/lib/actions/import.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { BaseDeployOptions } from './deploy';

export interface ImportOptions extends Omit<BaseDeployOptions, 'reuseAssets' | 'hotswap'> {
/**
* Build a physical resource mapping and write it to the given file, without performing the actual import operation
*
* @default - No file
*/
readonly recordResourceMapping?: string;

/**
* Path to a file with the physical resource mapping to CDK constructs in JSON format
*
* @default - No mapping file
*/
readonly resourceMappingFile?: string;

/**
* Allow non-addition changes to the template
*
* @default false
*/
readonly force?: boolean;
}
14 changes: 14 additions & 0 deletions packages/@aws-cdk/toolkit/lib/actions/synth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { StackSelector } from '../types';

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

/**
* After synthesis, validate stacks with the "validateOnSynth" attribute set (can also be controlled with CDK_VALIDATION)
* @default true
*/
readonly validateStacks?: boolean;
}
11 changes: 11 additions & 0 deletions packages/@aws-cdk/toolkit/lib/actions/watch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { BaseDeployOptions } from './deploy';

export interface WatchOptions extends BaseDeployOptions {
/**
* Whether to show CloudWatch logs for hotswapped resources
* locally in the users terminal
*
* @default - false
*/
readonly traceLogs?: boolean;
}
72 changes: 72 additions & 0 deletions packages/@aws-cdk/toolkit/lib/cloud-assembly-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { CloudAssembly } from '@aws-cdk/cx-api';

export interface ICloudAssemblySource {
/**
* produce
*/
produce(): Promise<CloudAssembly>;
}

/**
* Configuration for creating a CLI from an AWS CDK App directory
*/
export interface CdkAppDirectoryProps {
/**
* Command-line for executing your app or a cloud assembly directory
* e.g. "node bin/my-app.js"
* or
* "cdk.out"
*
* @default - read from cdk.json
*/
readonly app?: string;

/**
* Emits the synthesized cloud assembly into a directory
*
* @default cdk.out
*/
readonly output?: string;
}

export class CloudAssemblySource implements ICloudAssemblySource {
/**
* Use a directory containing an AWS CDK app as source.
* @param directory the directory of the AWS CDK app. Defaults to the current working directory.
* @param props additional configuration properties
* @returns an instance of `AwsCdkCli`
*/
public static fromCdkAppDirectory(_directory?: string, _props: CdkAppDirectoryProps = {}) {}

/**
* Create the CLI from a Cloud Assembly builder function.
*/
public static fromAssemblyBuilder(_builder: (context: Record<string, any>) => Promise<CloudAssembly>) {}

public produce(): Promise<CloudAssembly> {
throw new Error('Method not implemented.');
}
}

/**
* A CloudAssemblySource that is caching its result once produced.
*
* Most Toolkit interactions should use a cached source.
* Not caching is relevant when the source changes frequently
* and it is to expensive to predict if the source has changed.
*/
export class CachedCloudAssemblySource implements ICloudAssemblySource {
private source: ICloudAssemblySource;
private cloudAssembly: CloudAssembly | undefined;

public constructor(source: ICloudAssemblySource) {
this.source = source;
}

public async produce(): Promise<CloudAssembly> {
if (!this.cloudAssembly) {
this.cloudAssembly = await this.source.produce();
}
return this.cloudAssembly;
}
}
11 changes: 10 additions & 1 deletion packages/@aws-cdk/toolkit/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
export class Toolkit {}
export * from './toolkit';
export * from './cloud-assembly-source';
export * from './actions/deploy';
export * from './actions/destroy';
export * from './actions/import';
export * from './actions/synth';
export * from './actions/watch';

export * from './io-host';
export * from './types';
Loading

0 comments on commit dcf1d74

Please sign in to comment.