diff --git a/packages/@aws-cdk/aws-cloudformation/lib/custom-resource.ts b/packages/@aws-cdk/aws-cloudformation/lib/custom-resource.ts index a36411c8504f3..9c30e6c08540c 100644 --- a/packages/@aws-cdk/aws-cloudformation/lib/custom-resource.ts +++ b/packages/@aws-cdk/aws-cloudformation/lib/custom-resource.ts @@ -8,11 +8,15 @@ import { Construct } from '@aws-cdk/core'; /** * Collection of arbitrary properties + * + * @deprecated this type has been deprecated in favor of using a key-value type directly */ export type Properties = {[key: string]: any}; /** * Configuration options for custom resource providers. + * + * @deprecated used in {@link ICustomResourceProvider} which is now deprecated */ export interface CustomResourceProviderConfig { /** @@ -37,6 +41,8 @@ export interface ICustomResourceProvider { /** * Represents a provider for an AWS CloudFormation custom resources. + * + * @deprecated use core.CustomResource instead */ export class CustomResourceProvider implements ICustomResourceProvider { /** diff --git a/packages/@aws-cdk/aws-cloudformation/lib/nested-stack.ts b/packages/@aws-cdk/aws-cloudformation/lib/nested-stack.ts index 81487ac1470b4..57268c5291bb9 100644 --- a/packages/@aws-cdk/aws-cloudformation/lib/nested-stack.ts +++ b/packages/@aws-cdk/aws-cloudformation/lib/nested-stack.ts @@ -8,7 +8,7 @@ import { Construct } from '@aws-cdk/core'; /** * Initialization props for the `NestedStack` construct. * - * @experimental + * @deprecated use core.NestedStackProps instead */ export interface NestedStackProps { /** @@ -64,7 +64,7 @@ export interface NestedStackProps { * nested stack will automatically be translated to stack parameters and * outputs. * - * @experimental + * @deprecated use core.NestedStack instead */ export class NestedStack extends core.NestedStack { constructor(scope: Construct, id: string, props: NestedStackProps = { }) { diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts index b4a300d887ad4..63618e086ed91 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts @@ -168,9 +168,25 @@ interface CloudFormationDeployActionProps extends CloudFormationActionProps { * * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html#using-iam-capabilities * @default None, unless `adminPermissions` is true + * @deprecated use {@link cfnCapabilities} instead */ readonly capabilities?: cloudformation.CloudFormationCapabilities[]; + /** + * Acknowledge certain changes made as part of deployment. + * + * For stacks that contain certain resources, + * explicit acknowledgement is required that AWS CloudFormation might create or update those resources. + * For example, you must specify `ANONYMOUS_IAM` or `NAMED_IAM` if your stack template contains AWS + * Identity and Access Management (IAM) resources. + * For more information, see the link below. + * + * @default None, unless `adminPermissions` is true + * + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html#using-iam-capabilities + */ + readonly cfnCapabilities?: cdk.CfnCapabilities[]; + /** * Whether to grant full permissions to CloudFormation while deploying this template. * @@ -301,9 +317,18 @@ abstract class CloudFormationDeployAction extends CloudFormationAction { SingletonPolicy.forRole(options.role).grantPassRole(this._deploymentRole); - const capabilities = this.props2.adminPermissions && this.props2.capabilities === undefined - ? [cloudformation.CloudFormationCapabilities.NAMED_IAM] - : this.props2.capabilities; + const providedCapabilities = this.props2.cfnCapabilities ?? + this.props2.capabilities?.map(c => { + switch (c) { + case cloudformation.CloudFormationCapabilities.NONE: return cdk.CfnCapabilities.NONE; + case cloudformation.CloudFormationCapabilities.ANONYMOUS_IAM: return cdk.CfnCapabilities.ANONYMOUS_IAM; + case cloudformation.CloudFormationCapabilities.NAMED_IAM: return cdk.CfnCapabilities.NAMED_IAM; + case cloudformation.CloudFormationCapabilities.AUTO_EXPAND: return cdk.CfnCapabilities.AUTO_EXPAND; + } + }); + const capabilities = this.props2.adminPermissions && providedCapabilities === undefined + ? [cdk.CfnCapabilities.NAMED_IAM] + : providedCapabilities; const actionConfig = super.bound(scope, stage, options); return { @@ -620,7 +645,7 @@ interface StatementTemplate { type StatementCondition = { [op: string]: { [attribute: string]: string } }; -function parseCapabilities(capabilities: cloudformation.CloudFormationCapabilities[] | undefined): string | undefined { +function parseCapabilities(capabilities: cdk.CfnCapabilities[] | undefined): string | undefined { if (capabilities === undefined) { return undefined; } else if (capabilities.length === 1) { diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.cloudformation-pipeline-actions.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.cloudformation-pipeline-actions.ts index 31510ac049449..22bf46a15a641 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.cloudformation-pipeline-actions.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.cloudformation-pipeline-actions.ts @@ -558,6 +558,48 @@ export = { test.done(); }, + 'can use CfnCapabilities from the core module'(test: Test) { + // GIVEN + const stack = new TestFixture(); + + // WHEN + stack.deployStage.addAction(new cpactions.CloudFormationCreateUpdateStackAction({ + actionName: 'CreateUpdate', + stackName: 'MyStack', + templatePath: stack.sourceOutput.atPath('template.yaml'), + adminPermissions: false, + cfnCapabilities: [ + cdk.CfnCapabilities.NAMED_IAM, + cdk.CfnCapabilities.AUTO_EXPAND, + ], + })); + + // THEN: Action in Pipeline has named IAM and AUTOEXPAND capabilities + expect(stack).to(haveResourceLike('AWS::CodePipeline::Pipeline', { + 'Stages': [ + { 'Name': 'Source' /* don't care about the rest */ }, + { + 'Name': 'Deploy', + 'Actions': [ + { + 'Configuration': { + 'Capabilities': 'CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND', + 'RoleArn': { 'Fn::GetAtt': ['PipelineDeployCreateUpdateRole515CB7D4', 'Arn'] }, + 'ActionMode': 'CREATE_UPDATE', + 'StackName': 'MyStack', + 'TemplatePath': 'SourceArtifact::template.yaml', + }, + 'InputArtifacts': [{ 'Name': 'SourceArtifact' }], + 'Name': 'CreateUpdate', + }, + ], + }, + ], + })); + + test.done(); + }, + 'cross-account CFN Pipeline': { 'correctly creates the deployment Role in the other account'(test: Test) { const app = new cdk.App(); diff --git a/packages/@aws-cdk/pipelines/lib/actions/deploy-cdk-stack-action.ts b/packages/@aws-cdk/pipelines/lib/actions/deploy-cdk-stack-action.ts index 9fe520112931f..592b5b93e3855 100644 --- a/packages/@aws-cdk/pipelines/lib/actions/deploy-cdk-stack-action.ts +++ b/packages/@aws-cdk/pipelines/lib/actions/deploy-cdk-stack-action.ts @@ -1,11 +1,10 @@ import * as fs from 'fs'; import * as path from 'path'; -import * as cfn from '@aws-cdk/aws-cloudformation'; import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as cpactions from '@aws-cdk/aws-codepipeline-actions'; import * as events from '@aws-cdk/aws-events'; import * as iam from '@aws-cdk/aws-iam'; -import { Aws, Stack } from '@aws-cdk/core'; +import { Aws, CfnCapabilities, Stack } from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; import { Construct, Node } from 'constructs'; import { appOf, assemblyBuilderOf } from '../private/construct-internals'; @@ -249,7 +248,7 @@ export class DeployCdkStackAction implements codepipeline.IAction { role: props.actionRole, deploymentRole: props.cloudFormationExecutionRole, region: props.region, - capabilities: [cfn.CloudFormationCapabilities.NAMED_IAM, cfn.CloudFormationCapabilities.AUTO_EXPAND], + cfnCapabilities: [CfnCapabilities.NAMED_IAM, CfnCapabilities.AUTO_EXPAND], templateConfiguration: props.templateConfigurationPath ? props.cloudAssemblyInput.atPath(props.templateConfigurationPath) : undefined, }); this.executeChangeSetAction = new cpactions.CloudFormationExecuteChangeSetAction({ @@ -378,4 +377,4 @@ interface TemplateConfiguration { */ function writeTemplateConfiguration(filename: string, config: TemplateConfiguration) { fs.writeFileSync(filename, JSON.stringify(config, undefined, 2), { encoding: 'utf-8' }); -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/pipelines/package.json b/packages/@aws-cdk/pipelines/package.json index 6df06d00c1846..b13b5877cace7 100644 --- a/packages/@aws-cdk/pipelines/package.json +++ b/packages/@aws-cdk/pipelines/package.json @@ -50,8 +50,7 @@ "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", - "@aws-cdk/cx-api": "0.0.0", - "@aws-cdk/aws-cloudformation": "0.0.0" + "@aws-cdk/cx-api": "0.0.0" }, "dependencies": { "constructs": "^3.2.0", @@ -64,8 +63,7 @@ "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", - "@aws-cdk/cx-api": "0.0.0", - "@aws-cdk/aws-cloudformation": "0.0.0" + "@aws-cdk/cx-api": "0.0.0" }, "bundledDependencies": [], "keywords": [