この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
cdk bootstrapとは
cdk appを新しい環境(AWSアカウント x リージョン)でデプロイする際に、最初の一回だけ実行が必要なコマンドです。もう少し厳密に言うと、各環境(AWSアカウント x リージョン)にて以下いずれかに当てはまるappを初めてデプロイする際に必要になります。
- アセットを必要とするスタックがある場合
- 50キロバイトを超えるCFnテンプレートが生成される場合
- DefaultSynthesizerを使用するスタックがある場合
cdk bootstrapコマンドを実行すると、CFn(CloudFormation)スタックが作成され、cdk appのデプロイに必要な周辺リソースが作成されます。
modern (vs legacy)
cdk bootstrapで作成されるCFnスタックで使われるCFnテンプレートには大別して2種類存在します。modern templateとlegacy templateです。もともとはlegacyのみ存在していて後にmodernが登場しました。2022年2月現在はどちらも利用可能です。
この2種類のtemplateにどういう違いがあるのか、特にlegacyからmodernに変わって何が改良されたのか興味が湧いたので調べてみました。
とりあえず modern/legacy両方やってみた
cdk bootstrap --show-template
でbootstrapコマンドで作成されるCFn(CloudFormation) スタックのテンプレートが出力できます。modern/legacy版両方で出力して差分を調べてみました。cdkのバージョンは 1.142.0です。
modern版への切り替え方
CDK v1では v1.25.0以降からmodern版が利用可能ですが、legacy版がデフォルトです。(v2ではmodern版しか利用できません)
v1でmodern版を利用したい場合、以下いずれかの方法を使います。
環境変数を使う
環境変数 CDK_NEW_BOOTSTRAP
に1をセットした状態でbootstrapコマンドを実行します。
% export CDK_NEW_BOOTSTRAP=1
% cdk bootstrap --show-template > modern-bootstrap.yaml
CDK_NEW_BOOTSTRAP set, using new-style bootstrapping
cdk.json
内のフィーチャーフラグをセットする
bootstrapコマンドをcdkのappのディレクトリ上で実行する場合は、そのappのcdk.json
内のフィーチャーフラグを@aws-cdk/core:newStyleStackSynthesis
をtrue
にセットする方法でもいけます。
cdk.json
{
"app": "npx ts-node --prefer-ts-exts bin/modern.ts",
"context": {
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
"@aws-cdk/core:enableStackNameDuplicates": "true",
"@aws-cdk/core:newStyleStackSynthesis": true,
"aws-cdk:enableDiffNoFail": "true",
"@aws-cdk/core:stackRelativeExports": "true",
"@aws-cdk/aws-ecr-assets:dockerIgnoreSupport": true,
"@aws-cdk/aws-secretsmanager:parseOwnedSecretName": true,
"@aws-cdk/aws-kms:defaultKeyPolicies": true,
"@aws-cdk/aws-s3:grantWriteWithoutAcl": true,
"@aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount": true,
"@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
"@aws-cdk/aws-efs:defaultEncryptionAtRest": true,
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true
}
}
% npx cdk bootstrap --show-template > modern-bootstrap.yaml
'@aws-cdk/core:newStyleStackSynthesis' context set, using new-style bootstrapping
というわけで両方のテンプレートを出力してみました。
legacyのテンプレート
Description: The CDK Toolkit Stack. It was created by `cdk bootstrap` and manages resources necessary for managing your Cloud Applications with AWS CDK.
Conditions:
UsePublicAccessBlockConfiguration:
Fn::Equals:
- "true"
- "true"
Resources:
StagingBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: null
AccessControl: Private
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
KMSMasterKeyID: null
PublicAccessBlockConfiguration:
Fn::If:
- UsePublicAccessBlockConfiguration
- BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
- Ref: AWS::NoValue
StagingBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: StagingBucket
PolicyDocument:
Id: AccessControl
Version: "2012-10-17"
Statement:
- Sid: AllowSSLRequestsOnly
Action: s3:*
Effect: Deny
Resource:
- Fn::Sub: ${StagingBucket.Arn}
- Fn::Sub: ${StagingBucket.Arn}/*
Condition:
Bool:
aws:SecureTransport: "false"
Principal: "*"
Outputs:
BucketName:
Description: The name of the S3 bucket owned by the CDK toolkit stack
Value:
Ref: StagingBucket
BucketDomainName:
Description: The domain name of the S3 bucket owned by the CDK toolkit stack
Value:
Fn::GetAtt:
- StagingBucket
- RegionalDomainName
modernのテンプレート
Description: This stack includes resources needed to deploy AWS CDK apps into this environment
Parameters:
TrustedAccounts:
Description: List of AWS accounts that are trusted to publish assets and deploy stacks to this environment
Default: ""
Type: CommaDelimitedList
TrustedAccountsForLookup:
Description: List of AWS accounts that are trusted to look up values in this environment
Default: ""
Type: CommaDelimitedList
CloudFormationExecutionPolicies:
Description: List of the ManagedPolicy ARN(s) to attach to the CloudFormation deployment role
Default: ""
Type: CommaDelimitedList
FileAssetsBucketName:
Description: The name of the S3 bucket used for file assets
Default: ""
Type: String
FileAssetsBucketKmsKeyId:
Description: Empty to create a new key (default), 'AWS_MANAGED_KEY' to use a managed S3 key, or the ID/ARN of an existing key.
Default: ""
Type: String
ContainerAssetsRepositoryName:
Description: A user-provided custom name to use for the container assets ECR repository
Default: ""
Type: String
Qualifier:
Description: An identifier to distinguish multiple bootstrap stacks in the same environment
Default: hnb659fds
Type: String
AllowedPattern: "[A-Za-z0-9_-]{1,10}"
ConstraintDescription: Qualifier must be an alphanumeric identifier of at most 10 characters
PublicAccessBlockConfiguration:
Description: Whether or not to enable S3 Staging Bucket Public Access Block Configuration
Default: "true"
Type: String
AllowedValues:
- "true"
- "false"
Conditions:
HasTrustedAccounts:
Fn::Not:
- Fn::Equals:
- ""
- Fn::Join:
- ""
- Ref: TrustedAccounts
HasTrustedAccountsForLookup:
Fn::Not:
- Fn::Equals:
- ""
- Fn::Join:
- ""
- Ref: TrustedAccountsForLookup
HasCloudFormationExecutionPolicies:
Fn::Not:
- Fn::Equals:
- ""
- Fn::Join:
- ""
- Ref: CloudFormationExecutionPolicies
HasCustomFileAssetsBucketName:
Fn::Not:
- Fn::Equals:
- ""
- Ref: FileAssetsBucketName
CreateNewKey:
Fn::Equals:
- ""
- Ref: FileAssetsBucketKmsKeyId
UseAwsManagedKey:
Fn::Equals:
- AWS_MANAGED_KEY
- Ref: FileAssetsBucketKmsKeyId
HasCustomContainerAssetsRepositoryName:
Fn::Not:
- Fn::Equals:
- ""
- Ref: ContainerAssetsRepositoryName
UsePublicAccessBlockConfiguration:
Fn::Equals:
- "true"
- Ref: PublicAccessBlockConfiguration
Resources:
FileAssetsBucketEncryptionKey:
Type: AWS::KMS::Key
Properties:
KeyPolicy:
Statement:
- Action:
- kms:Create*
- kms:Describe*
- kms:Enable*
- kms:List*
- kms:Put*
- kms:Update*
- kms:Revoke*
- kms:Disable*
- kms:Get*
- kms:Delete*
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
- kms:GenerateDataKey
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
Resource: "*"
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS: "*"
Resource: "*"
Condition:
StringEquals:
kms:CallerAccount:
Ref: AWS::AccountId
kms:ViaService:
- Fn::Sub: s3.${AWS::Region}.amazonaws.com
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Principal:
AWS:
Fn::Sub: ${FilePublishingRole.Arn}
Resource: "*"
Condition: CreateNewKey
FileAssetsBucketEncryptionKeyAlias:
Condition: CreateNewKey
Type: AWS::KMS::Alias
Properties:
AliasName:
Fn::Sub: alias/cdk-${Qualifier}-assets-key
TargetKeyId:
Ref: FileAssetsBucketEncryptionKey
StagingBucket:
Type: AWS::S3::Bucket
Properties:
BucketName:
Fn::If:
- HasCustomFileAssetsBucketName
- Fn::Sub: ${FileAssetsBucketName}
- Fn::Sub: cdk-${Qualifier}-assets-${AWS::AccountId}-${AWS::Region}
AccessControl: Private
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
KMSMasterKeyID:
Fn::If:
- CreateNewKey
- Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
- Fn::If:
- UseAwsManagedKey
- Ref: AWS::NoValue
- Fn::Sub: ${FileAssetsBucketKmsKeyId}
PublicAccessBlockConfiguration:
Fn::If:
- UsePublicAccessBlockConfiguration
- BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
- Ref: AWS::NoValue
VersioningConfiguration:
Status: Enabled
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
StagingBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: StagingBucket
PolicyDocument:
Id: AccessControl
Version: "2012-10-17"
Statement:
- Sid: AllowSSLRequestsOnly
Action: s3:*
Effect: Deny
Resource:
- Fn::Sub: ${StagingBucket.Arn}
- Fn::Sub: ${StagingBucket.Arn}/*
Condition:
Bool:
aws:SecureTransport: "false"
Principal: "*"
ContainerAssetsRepository:
Type: AWS::ECR::Repository
Properties:
ImageScanningConfiguration:
ScanOnPush: true
RepositoryName:
Fn::If:
- HasCustomContainerAssetsRepositoryName
- Fn::Sub: ${ContainerAssetsRepositoryName}
- Fn::Sub: cdk-${Qualifier}-container-assets-${AWS::AccountId}-${AWS::Region}
FilePublishingRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Fn::If:
- HasTrustedAccounts
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccounts
- Ref: AWS::NoValue
RoleName:
Fn::Sub: cdk-${Qualifier}-file-publishing-role-${AWS::AccountId}-${AWS::Region}
Tags:
- Key: aws-cdk:bootstrap-role
Value: file-publishing
ImagePublishingRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Fn::If:
- HasTrustedAccounts
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccounts
- Ref: AWS::NoValue
RoleName:
Fn::Sub: cdk-${Qualifier}-image-publishing-role-${AWS::AccountId}-${AWS::Region}
Tags:
- Key: aws-cdk:bootstrap-role
Value: image-publishing
LookupRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Fn::If:
- HasTrustedAccountsForLookup
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccountsForLookup
- Ref: AWS::NoValue
- Fn::If:
- HasTrustedAccounts
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccounts
- Ref: AWS::NoValue
RoleName:
Fn::Sub: cdk-${Qualifier}-lookup-role-${AWS::AccountId}-${AWS::Region}
ManagedPolicyArns:
- Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/ReadOnlyAccess
Policies:
- PolicyDocument:
Statement:
- Sid: DontReadSecrets
Effect: Deny
Action:
- kms:Decrypt
Resource: "*"
Version: "2012-10-17"
PolicyName: LookupRolePolicy
Tags:
- Key: aws-cdk:bootstrap-role
Value: lookup
FilePublishingRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- s3:GetObject*
- s3:GetBucket*
- FilePublishingRoleDefaultPolicy
- s3:List*
- s3:DeleteObject*
- s3:PutObject*
- s3:Abort*
Resource:
- Fn::Sub: ${StagingBucket.Arn}
- Fn::Sub: ${StagingBucket.Arn}/*
Effect: Allow
- Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource:
Fn::If:
- CreateNewKey
- Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
- Fn::Sub: arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${FileAssetsBucketKmsKeyId}
Version: "2012-10-17"
Roles:
- Ref: FilePublishingRole
PolicyName:
Fn::Sub: cdk-${Qualifier}-file-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}
ImagePublishingRoleDefaultPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- ecr:PutImage
- ecr:InitiateLayerUpload
- ecr:UploadLayerPart
- ecr:CompleteLayerUpload
- ecr:BatchCheckLayerAvailability
- ecr:DescribeRepositories
- ecr:DescribeImages
- ecr:BatchGetImage
- ecr:GetDownloadUrlForLayer
Resource:
Fn::Sub: ${ContainerAssetsRepository.Arn}
Effect: Allow
- Action:
- ecr:GetAuthorizationToken
Resource: "*"
Effect: Allow
Version: "2012-10-17"
Roles:
- Ref: ImagePublishingRole
PolicyName:
Fn::Sub: cdk-${Qualifier}-image-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}
DeploymentActionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- Fn::If:
- HasTrustedAccounts
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS:
Ref: TrustedAccounts
- Ref: AWS::NoValue
Policies:
- PolicyDocument:
Statement:
- Sid: CloudFormationPermissions
Effect: Allow
Action:
- cloudformation:CreateChangeSet
- cloudformation:DeleteChangeSet
- cloudformation:DescribeChangeSet
- cloudformation:DescribeStacks
- cloudformation:ExecuteChangeSet
- cloudformation:CreateStack
- cloudformation:UpdateStack
Resource: "*"
- Sid: PipelineCrossAccountArtifactsBucket
Effect: Allow
Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
- s3:Abort*
- s3:DeleteObject*
- s3:PutObject*
Resource: "*"
Condition:
StringNotEquals:
s3:ResourceAccount:
Ref: AWS::AccountId
- Sid: PipelineCrossAccountArtifactsKey
Effect: Allow
Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Resource: "*"
Condition:
StringEquals:
kms:ViaService:
Fn::Sub: s3.${AWS::Region}.amazonaws.com
- Action: iam:PassRole
Resource:
Fn::Sub: ${CloudFormationExecutionRole.Arn}
Effect: Allow
- Sid: CliPermissions
Action:
- cloudformation:DescribeStackEvents
- cloudformation:GetTemplate
- cloudformation:DeleteStack
- cloudformation:UpdateTerminationProtection
- sts:GetCallerIdentity
Resource: "*"
Effect: Allow
- Sid: CliStagingBucket
Effect: Allow
Action:
- s3:GetObject*
- s3:GetBucket*
- s3:List*
Resource:
- Fn::Sub: ${StagingBucket.Arn}
- Fn::Sub: ${StagingBucket.Arn}/*
- Sid: ReadVersion
Effect: Allow
Action:
- ssm:GetParameter
Resource:
- Fn::Sub: arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter${CdkBootstrapVersion}
Version: "2012-10-17"
PolicyName: default
RoleName:
Fn::Sub: cdk-${Qualifier}-deploy-role-${AWS::AccountId}-${AWS::Region}
Tags:
- Key: aws-cdk:bootstrap-role
Value: deploy
CloudFormationExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: cloudformation.amazonaws.com
Version: "2012-10-17"
ManagedPolicyArns:
Fn::If:
- HasCloudFormationExecutionPolicies
- Ref: CloudFormationExecutionPolicies
- Fn::If:
- HasTrustedAccounts
- Ref: AWS::NoValue
- - Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess
RoleName:
Fn::Sub: cdk-${Qualifier}-cfn-exec-role-${AWS::AccountId}-${AWS::Region}
CdkBootstrapVersion:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name:
Fn::Sub: /cdk-bootstrap/${Qualifier}/version
Value: "10"
Outputs:
BucketName:
Description: The name of the S3 bucket owned by the CDK toolkit stack
Value:
Fn::Sub: ${StagingBucket}
BucketDomainName:
Description: The domain name of the S3 bucket owned by the CDK toolkit stack
Value:
Fn::Sub: ${StagingBucket.RegionalDomainName}
FileAssetKeyArn:
Description: The ARN of the KMS key used to encrypt the asset bucket (deprecated)
Value:
Fn::If:
- CreateNewKey
- Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
- Fn::Sub: ${FileAssetsBucketKmsKeyId}
Export:
Name:
Fn::Sub: CdkBootstrap-${Qualifier}-FileAssetKeyArn
ImageRepositoryName:
Description: The name of the ECR repository which hosts docker image assets
Value:
Fn::Sub: ${ContainerAssetsRepository}
BootstrapVersion:
Description: The version of the bootstrap resources that are currently mastered in this stack
Value:
Fn::GetAtt:
- CdkBootstrapVersion
- Value
diff
diffも取ってみました。
--- bootstrap-template-legacy.yaml 2022-01-28 15:54:29.000000000 +0900
+++ bootstrap-template-modern.yaml 2022-01-28 18:41:30.000000000 +0900
@@ -1,20 +1,168 @@
-Description: The CDK Toolkit Stack. It was created by `cdk bootstrap` and manages resources necessary for managing your Cloud Applications with AWS CDK.
+Description: This stack includes resources needed to deploy AWS CDK apps into this environment
+Parameters:
+ TrustedAccounts:
+ Description: List of AWS accounts that are trusted to publish assets and deploy stacks to this environment
+ Default: ""
+ Type: CommaDelimitedList
+ TrustedAccountsForLookup:
+ Description: List of AWS accounts that are trusted to look up values in this environment
+ Default: ""
+ Type: CommaDelimitedList
+ CloudFormationExecutionPolicies:
+ Description: List of the ManagedPolicy ARN(s) to attach to the CloudFormation deployment role
+ Default: ""
+ Type: CommaDelimitedList
+ FileAssetsBucketName:
+ Description: The name of the S3 bucket used for file assets
+ Default: ""
+ Type: String
+ FileAssetsBucketKmsKeyId:
+ Description: Empty to create a new key (default), 'AWS_MANAGED_KEY' to use a managed S3 key, or the ID/ARN of an existing key.
+ Default: ""
+ Type: String
+ ContainerAssetsRepositoryName:
+ Description: A user-provided custom name to use for the container assets ECR repository
+ Default: ""
+ Type: String
+ Qualifier:
+ Description: An identifier to distinguish multiple bootstrap stacks in the same environment
+ Default: hnb659fds
+ Type: String
+ AllowedPattern: "[A-Za-z0-9_-]{1,10}"
+ ConstraintDescription: Qualifier must be an alphanumeric identifier of at most 10 characters
+ PublicAccessBlockConfiguration:
+ Description: Whether or not to enable S3 Staging Bucket Public Access Block Configuration
+ Default: "true"
+ Type: String
+ AllowedValues:
+ - "true"
+ - "false"
Conditions:
+ HasTrustedAccounts:
+ Fn::Not:
+ - Fn::Equals:
+ - ""
+ - Fn::Join:
+ - ""
+ - Ref: TrustedAccounts
+ HasTrustedAccountsForLookup:
+ Fn::Not:
+ - Fn::Equals:
+ - ""
+ - Fn::Join:
+ - ""
+ - Ref: TrustedAccountsForLookup
+ HasCloudFormationExecutionPolicies:
+ Fn::Not:
+ - Fn::Equals:
+ - ""
+ - Fn::Join:
+ - ""
+ - Ref: CloudFormationExecutionPolicies
+ HasCustomFileAssetsBucketName:
+ Fn::Not:
+ - Fn::Equals:
+ - ""
+ - Ref: FileAssetsBucketName
+ CreateNewKey:
+ Fn::Equals:
+ - ""
+ - Ref: FileAssetsBucketKmsKeyId
+ UseAwsManagedKey:
+ Fn::Equals:
+ - AWS_MANAGED_KEY
+ - Ref: FileAssetsBucketKmsKeyId
+ HasCustomContainerAssetsRepositoryName:
+ Fn::Not:
+ - Fn::Equals:
+ - ""
+ - Ref: ContainerAssetsRepositoryName
UsePublicAccessBlockConfiguration:
Fn::Equals:
- "true"
- - "true"
+ - Ref: PublicAccessBlockConfiguration
Resources:
+ FileAssetsBucketEncryptionKey:
+ Type: AWS::KMS::Key
+ Properties:
+ KeyPolicy:
+ Statement:
+ - Action:
+ - kms:Create*
+ - kms:Describe*
+ - kms:Enable*
+ - kms:List*
+ - kms:Put*
+ - kms:Update*
+ - kms:Revoke*
+ - kms:Disable*
+ - kms:Get*
+ - kms:Delete*
+ - kms:ScheduleKeyDeletion
+ - kms:CancelKeyDeletion
+ - kms:GenerateDataKey
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: AWS::AccountId
+ Resource: "*"
+ - Action:
+ - kms:Decrypt
+ - kms:DescribeKey
+ - kms:Encrypt
+ - kms:ReEncrypt*
+ - kms:GenerateDataKey*
+ Effect: Allow
+ Principal:
+ AWS: "*"
+ Resource: "*"
+ Condition:
+ StringEquals:
+ kms:CallerAccount:
+ Ref: AWS::AccountId
+ kms:ViaService:
+ - Fn::Sub: s3.${AWS::Region}.amazonaws.com
+ - Action:
+ - kms:Decrypt
+ - kms:DescribeKey
+ - kms:Encrypt
+ - kms:ReEncrypt*
+ - kms:GenerateDataKey*
+ Effect: Allow
+ Principal:
+ AWS:
+ Fn::Sub: ${FilePublishingRole.Arn}
+ Resource: "*"
+ Condition: CreateNewKey
+ FileAssetsBucketEncryptionKeyAlias:
+ Condition: CreateNewKey
+ Type: AWS::KMS::Alias
+ Properties:
+ AliasName:
+ Fn::Sub: alias/cdk-${Qualifier}-assets-key
+ TargetKeyId:
+ Ref: FileAssetsBucketEncryptionKey
StagingBucket:
Type: AWS::S3::Bucket
Properties:
- BucketName: null
+ BucketName:
+ Fn::If:
+ - HasCustomFileAssetsBucketName
+ - Fn::Sub: ${FileAssetsBucketName}
+ - Fn::Sub: cdk-${Qualifier}-assets-${AWS::AccountId}-${AWS::Region}
AccessControl: Private
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
- KMSMasterKeyID: null
+ KMSMasterKeyID:
+ Fn::If:
+ - CreateNewKey
+ - Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
+ - Fn::If:
+ - UseAwsManagedKey
+ - Ref: AWS::NoValue
+ - Fn::Sub: ${FileAssetsBucketKmsKeyId}
PublicAccessBlockConfiguration:
Fn::If:
- UsePublicAccessBlockConfiguration
@@ -23,6 +171,10 @@
IgnorePublicAcls: true
RestrictPublicBuckets: true
- Ref: AWS::NoValue
+ VersioningConfiguration:
+ Status: Enabled
+ UpdateReplacePolicy: Retain
+ DeletionPolicy: Retain
StagingBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
@@ -42,15 +194,311 @@
Bool:
aws:SecureTransport: "false"
Principal: "*"
+ ContainerAssetsRepository:
+ Type: AWS::ECR::Repository
+ Properties:
+ ImageScanningConfiguration:
+ ScanOnPush: true
+ RepositoryName:
+ Fn::If:
+ - HasCustomContainerAssetsRepositoryName
+ - Fn::Sub: ${ContainerAssetsRepositoryName}
+ - Fn::Sub: cdk-${Qualifier}-container-assets-${AWS::AccountId}-${AWS::Region}
+ FilePublishingRole:
+ Type: AWS::IAM::Role
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: AWS::AccountId
+ - Fn::If:
+ - HasTrustedAccounts
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: TrustedAccounts
+ - Ref: AWS::NoValue
+ RoleName:
+ Fn::Sub: cdk-${Qualifier}-file-publishing-role-${AWS::AccountId}-${AWS::Region}
+ Tags:
+ - Key: aws-cdk:bootstrap-role
+ Value: file-publishing
+ ImagePublishingRole:
+ Type: AWS::IAM::Role
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: AWS::AccountId
+ - Fn::If:
+ - HasTrustedAccounts
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: TrustedAccounts
+ - Ref: AWS::NoValue
+ RoleName:
+ Fn::Sub: cdk-${Qualifier}-image-publishing-role-${AWS::AccountId}-${AWS::Region}
+ Tags:
+ - Key: aws-cdk:bootstrap-role
+ Value: image-publishing
+ LookupRole:
+ Type: AWS::IAM::Role
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: AWS::AccountId
+ - Fn::If:
+ - HasTrustedAccountsForLookup
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: TrustedAccountsForLookup
+ - Ref: AWS::NoValue
+ - Fn::If:
+ - HasTrustedAccounts
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: TrustedAccounts
+ - Ref: AWS::NoValue
+ RoleName:
+ Fn::Sub: cdk-${Qualifier}-lookup-role-${AWS::AccountId}-${AWS::Region}
+ ManagedPolicyArns:
+ - Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/ReadOnlyAccess
+ Policies:
+ - PolicyDocument:
+ Statement:
+ - Sid: DontReadSecrets
+ Effect: Deny
+ Action:
+ - kms:Decrypt
+ Resource: "*"
+ Version: "2012-10-17"
+ PolicyName: LookupRolePolicy
+ Tags:
+ - Key: aws-cdk:bootstrap-role
+ Value: lookup
+ FilePublishingRoleDefaultPolicy:
+ Type: AWS::IAM::Policy
+ Properties:
+ PolicyDocument:
+ Statement:
+ - Action:
+ - s3:GetObject*
+ - s3:GetBucket*
+ - FilePublishingRoleDefaultPolicy
+ - s3:List*
+ - s3:DeleteObject*
+ - s3:PutObject*
+ - s3:Abort*
+ Resource:
+ - Fn::Sub: ${StagingBucket.Arn}
+ - Fn::Sub: ${StagingBucket.Arn}/*
+ Effect: Allow
+ - Action:
+ - kms:Decrypt
+ - kms:DescribeKey
+ - kms:Encrypt
+ - kms:ReEncrypt*
+ - kms:GenerateDataKey*
+ Effect: Allow
+ Resource:
+ Fn::If:
+ - CreateNewKey
+ - Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
+ - Fn::Sub: arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${FileAssetsBucketKmsKeyId}
+ Version: "2012-10-17"
+ Roles:
+ - Ref: FilePublishingRole
+ PolicyName:
+ Fn::Sub: cdk-${Qualifier}-file-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}
+ ImagePublishingRoleDefaultPolicy:
+ Type: AWS::IAM::Policy
+ Properties:
+ PolicyDocument:
+ Statement:
+ - Action:
+ - ecr:PutImage
+ - ecr:InitiateLayerUpload
+ - ecr:UploadLayerPart
+ - ecr:CompleteLayerUpload
+ - ecr:BatchCheckLayerAvailability
+ - ecr:DescribeRepositories
+ - ecr:DescribeImages
+ - ecr:BatchGetImage
+ - ecr:GetDownloadUrlForLayer
+ Resource:
+ Fn::Sub: ${ContainerAssetsRepository.Arn}
+ Effect: Allow
+ - Action:
+ - ecr:GetAuthorizationToken
+ Resource: "*"
+ Effect: Allow
+ Version: "2012-10-17"
+ Roles:
+ - Ref: ImagePublishingRole
+ PolicyName:
+ Fn::Sub: cdk-${Qualifier}-image-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}
+ DeploymentActionRole:
+ Type: AWS::IAM::Role
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: AWS::AccountId
+ - Fn::If:
+ - HasTrustedAccounts
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ AWS:
+ Ref: TrustedAccounts
+ - Ref: AWS::NoValue
+ Policies:
+ - PolicyDocument:
+ Statement:
+ - Sid: CloudFormationPermissions
+ Effect: Allow
+ Action:
+ - cloudformation:CreateChangeSet
+ - cloudformation:DeleteChangeSet
+ - cloudformation:DescribeChangeSet
+ - cloudformation:DescribeStacks
+ - cloudformation:ExecuteChangeSet
+ - cloudformation:CreateStack
+ - cloudformation:UpdateStack
+ Resource: "*"
+ - Sid: PipelineCrossAccountArtifactsBucket
+ Effect: Allow
+ Action:
+ - s3:GetObject*
+ - s3:GetBucket*
+ - s3:List*
+ - s3:Abort*
+ - s3:DeleteObject*
+ - s3:PutObject*
+ Resource: "*"
+ Condition:
+ StringNotEquals:
+ s3:ResourceAccount:
+ Ref: AWS::AccountId
+ - Sid: PipelineCrossAccountArtifactsKey
+ Effect: Allow
+ Action:
+ - kms:Decrypt
+ - kms:DescribeKey
+ - kms:Encrypt
+ - kms:ReEncrypt*
+ - kms:GenerateDataKey*
+ Resource: "*"
+ Condition:
+ StringEquals:
+ kms:ViaService:
+ Fn::Sub: s3.${AWS::Region}.amazonaws.com
+ - Action: iam:PassRole
+ Resource:
+ Fn::Sub: ${CloudFormationExecutionRole.Arn}
+ Effect: Allow
+ - Sid: CliPermissions
+ Action:
+ - cloudformation:DescribeStackEvents
+ - cloudformation:GetTemplate
+ - cloudformation:DeleteStack
+ - cloudformation:UpdateTerminationProtection
+ - sts:GetCallerIdentity
+ Resource: "*"
+ Effect: Allow
+ - Sid: CliStagingBucket
+ Effect: Allow
+ Action:
+ - s3:GetObject*
+ - s3:GetBucket*
+ - s3:List*
+ Resource:
+ - Fn::Sub: ${StagingBucket.Arn}
+ - Fn::Sub: ${StagingBucket.Arn}/*
+ - Sid: ReadVersion
+ Effect: Allow
+ Action:
+ - ssm:GetParameter
+ Resource:
+ - Fn::Sub: arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter${CdkBootstrapVersion}
+ Version: "2012-10-17"
+ PolicyName: default
+ RoleName:
+ Fn::Sub: cdk-${Qualifier}-deploy-role-${AWS::AccountId}-${AWS::Region}
+ Tags:
+ - Key: aws-cdk:bootstrap-role
+ Value: deploy
+ CloudFormationExecutionRole:
+ Type: AWS::IAM::Role
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action: sts:AssumeRole
+ Effect: Allow
+ Principal:
+ Service: cloudformation.amazonaws.com
+ Version: "2012-10-17"
+ ManagedPolicyArns:
+ Fn::If:
+ - HasCloudFormationExecutionPolicies
+ - Ref: CloudFormationExecutionPolicies
+ - Fn::If:
+ - HasTrustedAccounts
+ - Ref: AWS::NoValue
+ - - Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess
+ RoleName:
+ Fn::Sub: cdk-${Qualifier}-cfn-exec-role-${AWS::AccountId}-${AWS::Region}
+ CdkBootstrapVersion:
+ Type: AWS::SSM::Parameter
+ Properties:
+ Type: String
+ Name:
+ Fn::Sub: /cdk-bootstrap/${Qualifier}/version
+ Value: "10"
Outputs:
BucketName:
Description: The name of the S3 bucket owned by the CDK toolkit stack
Value:
- Ref: StagingBucket
+ Fn::Sub: ${StagingBucket}
BucketDomainName:
Description: The domain name of the S3 bucket owned by the CDK toolkit stack
Value:
+ Fn::Sub: ${StagingBucket.RegionalDomainName}
+ FileAssetKeyArn:
+ Description: The ARN of the KMS key used to encrypt the asset bucket (deprecated)
+ Value:
+ Fn::If:
+ - CreateNewKey
+ - Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
+ - Fn::Sub: ${FileAssetsBucketKmsKeyId}
+ Export:
+ Name:
+ Fn::Sub: CdkBootstrap-${Qualifier}-FileAssetKeyArn
+ ImageRepositoryName:
+ Description: The name of the ECR repository which hosts docker image assets
+ Value:
+ Fn::Sub: ${ContainerAssetsRepository}
+ BootstrapVersion:
+ Description: The version of the bootstrap resources that are currently mastered in this stack
+ Value:
Fn::GetAtt:
- - StagingBucket
- - RegionalDomainName
+ - CdkBootstrapVersion
+ - Value
ざっくりわかることは…Modern版の方がかなりテンプレートが大きく、作るリソースの種類が多いですね。
Resources
legacyで作成されるリソースは以下2つだけです。
- AWS::S3::Bucket
- AWS::S3::BucketPolicy
対してmodernには上記に加えて以下リソースが作成されます。
- AWS::SSM::Parameter
- AWS::IAM::Role 5つ
- AWS::ECR::Repository
- AWS::IAM::Policy 2つ
また条件次第で以下も作成されます。
- AWS::KMS::Key
- AWS::KMS::Alias
Outputs
新たに作られたKMSキーやECRリポジトリの情報が追加されています。またBootstrapVersion
なる項目もあります。
Parameters
legacyにはParametersはゼロですが、modernには8個あります。
結局 modern templateになって何が良くなるの?
ここまで書いておいてなんですが、正直テンプレートの差分自体はどうでも良いですよね。重要なのはこういった差分によって得られるメリットです。
デプロイ実行時の権限が分離される
legacyの場合、cdk appをcdk deploy
コマンドにて(CFnを介して)デプロイする際に使われる権限は、コマンドを実行したエンティティの権限です。aws sts get-caller-identity
コマンドで確認できるやつですね。
対してmodernではbootstrapスタックがプロビジョニングされたときに指定されたアクセス許可を使用してデプロイします。modern templateの中にIAM Roleが5つあると先程ご紹介しました。これが使われます。各ロールの詳細を説明します。
DeploymentActionRole
cdk deploy
などのcdkコマンドを打つと基本的にこのロールにassume roleしてからAWS上の操作を行なうようです。「基本的に」というのは、他のロールの責務外の箇所全部、という意味です。
CloudFormationExecutionRole
CDKはCFnテンプレートを生成してそのテンプレートをCFnに食わせて各リソースを作成するツールですが、CFnがリソースを作成する際に使われるロールです。以下で紹介されているIAM Roleを介してCFnを実行するやつです。
なお、これを実現するために、先のDeploymentActionRoleにCloudFormationExecutionRoleに対してのiam:PassRole
が許可されています。
また、このCloudFormationExecutionRoleは各リソースを作成する際に使われるロールですので、デフォルトではAdministratorAccessポリシーがアタッチされます。が、cdk bootstrap
コマンドの--cloudformation-execution-policies
で別のポリシーのARNを指定すれば上書きすることが可能です。
LookupRole
以下エントリで使われているVPC ConstructのfromLookup
static methodのようなfromLookup
メソッドを使う場合に使われるロールです。
各種fromLookup
メソッドは既存リソースを参照する際に使われるメソッドなので、このロールにはReadOnlyAccessマネージドポリシーがアタッチされます。
ImagePublishingRole
modern templateで作成されるECRリポジトリにアクセスするのに使われます。このECRリポジトリが使われるのは、cdk appの中でコンテナイメージをbuild、pushするような処理が必要な場合です。例えば以下のコードのような、特定のディレクトリ以下にあるDockerfileとソースコードを基にコンテナイメージを作り、それをLambda関数にするような場合です。
const getMovieFunction = new lambda.DockerImageFunction(this, 'getMovieFunction',{
functionName: 'getMovieFunction',
code: lambda.DockerImageCode.fromImageAsset(path.join(__dirname, '../../src/movie-service'), {
cmd: [ "get.get" ],
entrypoint: ["/lambda-entrypoint.sh"],
}),
environment: {
DYNAMODB_TABLE: this.table.tableName
},
});
以下は、上記とほぼ同じコードを使って cdk deploy -v
した際の出力の一部です。最初の行でImagePublishingRole(にて作成されたロール)にassume roleしてから、docker login
でECRレジストリにログインし、コンテナイメージをビルドし、タグ付けしプッシュ、ということが行われていることがわかるかと思います。
Assuming role 'arn:aws:iam::123456789012:role/cdk-hnb659fds-image-publishing-role-123456789012-us-east-1'.
[75%] check: Check 123456789012.dkr.ecr.us-east-1.amazonaws.com/cdk-hnb659fds-container-assets-123456789012-us-east-1:82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072
Call failed: describeImages({"repositoryName":"cdk-hnb659fds-container-assets-123456789012-us-east-1","imageIds":[{"imageTag":"82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072"}]}) => The image with imageId {imageDigest:'null', imageTag:'82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072'} does not exist within the repository with name 'cdk-hnb659fds-container-assets-123456789012-us-east-1' in the registry with id '123456789012' (code=ImageNotFoundException)
[75%] debug: docker login --username AWS --password-stdin https://123456789012.dkr.ecr.us-east-1.amazonaws.com
[75%] debug: docker inspect cdkasset-82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072
[75%] build: Building Docker image at /Users/kazue.masaki/hoge/cdk.out/asset.82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072
[75%] debug: docker build --tag cdkasset-82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072 .
#1 [internal] load build definition from Dockerfile
#1 sha256:f5f55ee88cf1c382b262f8e025d176d52d1b777c3d1930e1c8d3d5e203b90630
#1 transferring dockerfile: 331B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 sha256:5c5f981b13a8392382ffe9c1ddd1e354f5922dc3974bab6702b3192231cade5d
#2 transferring context: 2B done
#2 DONE 0.0s
#3 [internal] load metadata for public.ecr.aws/lambda/nodejs:12
#3 sha256:dffa778413db7fcfd0635689e67ed302cfc55e499bb3ec3f18f4be6f2c6d3375
#3 DONE 4.0s
#5 [internal] load build context
#5 sha256:f9b9c5c3c155c2d102874b2358df3cc2c54577508df465af93efbe31b9290404
#5 transferring context: 3.10kB 0.0s done
#5 DONE 0.0s
#4 [1/3] FROM public.ecr.aws/lambda/nodejs:12@sha256:0eb5179d02a6d6e095c048f752dd33a75263cf4136ced8787a83737228dc2354
#4 sha256:2d07cc1648b3d1bb43e4ec6303cc94d300c65d66aa31f384dcca620041a2bfd8
#4 resolve public.ecr.aws/lambda/nodejs:12@sha256:0eb5179d02a6d6e095c048f752dd33a75263cf4136ced8787a83737228dc2354 done
#4 sha256:0eb5179d02a6d6e095c048f752dd33a75263cf4136ced8787a83737228dc2354 772B / 772B done
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 0B / 102.54MB 0.1s
#4 sha256:0de26daf261e48dbc00f77c5fca094fefb2688e51d9dfc254e62da61caabf73a 0B / 81.51kB 0.1s
#4 sha256:c8880dcd4d4b595529cb48f73e39f9bda467a3fde8314e175bbc20db3e70d5e8 1.58kB / 1.58kB done
#4 sha256:42e1ffbbf5228b97e5bcbae3ac164b665f015c0ad1a6beb618abb37a0d827172 3.12kB / 3.12kB done
#4 sha256:0bd3404121966a38ff947eb711f2c1bd8ce9f3313ec50467acce079b545c8fd8 0B / 417B 0.1s
#4 sha256:0de26daf261e48dbc00f77c5fca094fefb2688e51d9dfc254e62da61caabf73a 81.51kB / 81.51kB 0.9s done
#4 sha256:ba3917f372fcb5f0400ef2e67fa308141dea840c07dd7cc3e3e4ef691d1b2a0b 0B / 2.11MB 1.0s
#4 sha256:0bd3404121966a38ff947eb711f2c1bd8ce9f3313ec50467acce079b545c8fd8 417B / 417B 1.1s done
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 0B / 36.29MB 1.3s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 5.24MB / 102.54MB 2.3s
#4 sha256:ba3917f372fcb5f0400ef2e67fa308141dea840c07dd7cc3e3e4ef691d1b2a0b 1.05MB / 2.11MB 2.4s
#4 sha256:ba3917f372fcb5f0400ef2e67fa308141dea840c07dd7cc3e3e4ef691d1b2a0b 2.11MB / 2.11MB 2.4s done
#4 sha256:446fafb864797ce9732c47ebba7d5a15244e49a309ef70767e91b29c80d46214 0B / 9.26MB 2.5s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 11.53MB / 102.54MB 2.6s
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 3.15MB / 36.29MB 2.9s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 17.83MB / 102.54MB 3.1s
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 9.44MB / 36.29MB 3.1s
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 13.63MB / 36.29MB 3.3s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 23.07MB / 102.54MB 3.5s
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 15.73MB / 36.29MB 3.6s
#4 sha256:446fafb864797ce9732c47ebba7d5a15244e49a309ef70767e91b29c80d46214 1.05MB / 9.26MB 3.6s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 28.31MB / 102.54MB 3.7s
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 17.83MB / 36.29MB 3.7s
#4 sha256:446fafb864797ce9732c47ebba7d5a15244e49a309ef70767e91b29c80d46214 2.10MB / 9.26MB 3.7s
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 22.02MB / 36.29MB 3.9s
#4 sha256:446fafb864797ce9732c47ebba7d5a15244e49a309ef70767e91b29c80d46214 5.24MB / 9.26MB 3.9s
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 27.26MB / 36.29MB 4.2s
#4 sha256:446fafb864797ce9732c47ebba7d5a15244e49a309ef70767e91b29c80d46214 9.26MB / 9.26MB 4.2s done
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 33.55MB / 102.54MB 4.3s
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 34.60MB / 36.29MB 4.5s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 41.94MB / 102.54MB 4.7s
#4 sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 36.29MB / 36.29MB 4.7s done
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 47.19MB / 102.54MB 5.2s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 53.48MB / 102.54MB 5.6s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 61.87MB / 102.54MB 5.9s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 69.21MB / 102.54MB 6.2s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 74.45MB / 102.54MB 6.5s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 80.74MB / 102.54MB 6.8s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 85.98MB / 102.54MB 7.1s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 92.27MB / 102.54MB 7.4s
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 100.66MB / 102.54MB 7.9s
#4 extracting sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9
#4 sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 102.54MB / 102.54MB 8.0s done
#4 extracting sha256:d4bbef92ccd41b6a71f82c32c66da512dff174187c784d4322aabe5d47244bb9 2.9s done
#4 extracting sha256:0de26daf261e48dbc00f77c5fca094fefb2688e51d9dfc254e62da61caabf73a 0.0s done
#4 extracting sha256:0bd3404121966a38ff947eb711f2c1bd8ce9f3313ec50467acce079b545c8fd8 done
#4 extracting sha256:ba3917f372fcb5f0400ef2e67fa308141dea840c07dd7cc3e3e4ef691d1b2a0b
#4 extracting sha256:ba3917f372fcb5f0400ef2e67fa308141dea840c07dd7cc3e3e4ef691d1b2a0b 0.1s done
#4 extracting sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 0.1s
#4 extracting sha256:14389da6c37f56d27f8498a2d48b3a27748bd1ffac7eb35cb7402a2da8f4a0b9 1.0s done
#4 extracting sha256:446fafb864797ce9732c47ebba7d5a15244e49a309ef70767e91b29c80d46214
#4 extracting sha256:446fafb864797ce9732c47ebba7d5a15244e49a309ef70767e91b29c80d46214 0.4s done
#4 DONE 13.1s
#6 [2/3] COPY list.js get.js package.json package-lock.json /var/task/
#6 sha256:0b050ecc3fb54d27aa842df1719d37d753529c6ab8fcf1c4d5d56eebea0e37c7
#6 DONE 0.1s
#7 [3/3] RUN npm install
#7 sha256:da30c0a7d837c2c108cd1e37c1d48f998e575ce9a60c364a331ec9e66fb3536e
#7 1.253 npm WARN movie-service@1.0.0 No repository field.
#7 1.253
#7 1.254 added 2 packages from 9 contributors and audited 2 packages in 0.906s
#7 1.255 found 0 vulnerabilities
#7 1.255
#7 DONE 1.3s
#8 exporting to image
#8 sha256:e8c613e07b0b7ff33893b694f7759a10d42e180f2b4dc349fb57dc6b71dcab00
#8 exporting layers 0.0s done
#8 writing image sha256:4bae9f552ad2d3320f5dc03cf009f229dea2565311c447b0bd4e3e100edc64a4 done
#8 naming to docker.io/library/cdkasset-82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072 done
#8 DONE 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[75%] upload: Push 123456789012.dkr.ecr.us-east-1.amazonaws.com/cdk-hnb659fds-container-assets-123456789012-us-east-1:82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072
[75%] debug: docker tag cdkasset-82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072 123456789012.dkr.ecr.us-east-1.amazonaws.com/cdk-hnb659fds-container-assets-123456789012-us-east-1:82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072
[75%] debug: docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/cdk-hnb659fds-container-assets-123456789012-us-east-1:82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072
The push refers to repository [123456789012.dkr.ecr.us-east-1.amazonaws.com/cdk-hnb659fds-container-assets-123456789012-us-east-1]
7a14e98d7d59: Preparing
4c85dd7eb7a5: Preparing
72a490fbf8cd: Preparing
083dc41d458c: Preparing
1a913cc9bc55: Preparing
050f1cc9348a: Preparing
20455b74816f: Preparing
6339f48a17fc: Preparing
050f1cc9348a: Waiting
20455b74816f: Waiting
6339f48a17fc: Waiting
4c85dd7eb7a5: Pushed
7a14e98d7d59: Pushed
1a913cc9bc55: Pushed
72a490fbf8cd: Pushed
050f1cc9348a: Pushed
20455b74816f: Pushed
083dc41d458c: Pushed
6339f48a17fc: Pushed
82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072: digest: sha256:9c0ffd5e70d8d67e865f645322d44d24e24daed35d681b6e5478c5e544f22910 size: 1997
[100%] success: Published 82f1f2c7b5ab440f870dedc0ba5775be95a3d13321b872e92656245d32791072:current_account-us-east-1
FilePublishingRole
前述のImagePublishingRoleと似ていますが、こちらはS3バケットにアセットをアップロードするときに使われるロールです。コンテナイメージからではなくソースコードからLambda関数を作成する際などに使われます。(対象のS3バケットもcdk bootstrap
によって作成されます。)
割愛しますが、cdk deploy -v
コマンドを打つとImagePublishingRoleと同様このロールにassume roleしてからオブジェクトをS3にアップロードしているのがわかります。
5つのロールまとめ
クロスアカウントデプロイメントができる
cdk bootstrap
コマンドに--trust
オプションを追加して値にAWSアカウントIDを指定します。するとそのアカウントからのデプロイが可能になります。具体的には、前項で説明した各種ロールの信頼関係ポリシーに指定したアカウントIDが追加されるので、そのアカウントからassume roleできるようになってデプロイできるようになります。CDK PipelineでクロスアカウントのCI/CDパイプラインを作る際に活用できます。
また--trust-for-lookup
というオプションもあります。こちらは前項のLookupRoleの信頼関係ポリシーのみ変更するオプションです。つまりこのオプションに指定されたアカウントからは、当アカウントの既存リソースについての参照はできるけれども、デプロイはできないという状態を作れます。
改良が続けられている
modern templateは改良が続けられていて、作成されるリソースが変わったりそのプロパティが変わったりしています。更新がかかる度にそれは新しいversionとなります。modern templateの中にAWS::SSM::Parameter
つまりパラメーターストアがありましたが、このパラメーターストアには紐づくbootstrap templateのバージョン番号が格納されています。cdk appのdeploy時にこのパラメーターストアの値をチェックして、bootstrapのバージョンがそのappの要件を満たしているかチェックします。
リソース命名方法をコントロールできる
bootstrap templateを介して作成される各AWSリソースには名前にランダムな文字列が付きます。legacyではこの文字列をコントロールすることはできません。が、modernではできます。--qualifier
オプションをつけてcdk bootstrap
コマンドを実行します。先程ご紹介した modern templateにQualifier
というパラメーターがあり、ここに--qualifier
オプション値が渡されてスタックが作成されます。そしてこのQualifier
パラメーターは各bootstrapリソースの名前を決定する際に使われています。例えば以下はS3バケットを作成する部分です。
StagingBucket:
Type: AWS::S3::Bucket
Properties:
BucketName:
Fn::If:
- HasCustomFileAssetsBucketName
- Fn::Sub: ${FileAssetsBucketName}
- Fn::Sub: cdk-${Qualifier}-assets-${AWS::AccountId}-${AWS::Region}
なおQualifier
デフォルト値はhnb659fds
なので、これが名前に含まれるリソースが作成されます。
この機能によって、同一環境(アカウントxリージョン)に複数個のbootstrapリソースを置きたい場合に、リソース名重複エラーを避けることができます。まあそもそも同一環境に複数個のbootstrapリソースを置きたい場合はあまりなさそうな気もしますが… コンプライアンス要件的にcdk app毎に使うbootstrapリソースも完全に分けたいとか、bootstrapリソースも色々カスタマイズできるので個々のapp要件に併せてカスタマイズしたものを使いたいとかですかね。
なおcdk app側で--qualifier
オプションで名前を変えたbootstrapリソース群を使うには、Stack Constructのsynthesizer propでqualifier
を指定します。
new MyStack(this, 'MyStack', {
synthesizer: new DefaultStackSynthesizer({
qualifier: 'MYQUALIFIER',
}),
});
もしくはcdk.json
内で@aws-cdk/core:bootstrapQualifier
を使います。
{
"app": "...",
"context": {
"@aws-cdk/core:bootstrapQualifier": "MYQUALIFIER"
}
}
バケット暗号化のキーが選べる
bootstrapで作成されるS3バケットですが、legacyだとAWS管理のKMSキーによってオブジェクトがサーバーサイド暗号化されます。modernだと以下3つの方法を選ぶことができます。
- AWS管理のKMSキー(legacyと同じ)
- 作成済みKMSキーを使う
- bootstrap内でKMSキーを作ってそれを使う
なおデフォルトはAWS管理のKMSキーです。
ガッツリカスタマイズもできる
cdk bootstrap --template my-bootstrap-template.yaml
のように--template
オプションで任意のCFnテンプレートを指定すれば、ガッツリbootstrapリソース達のカスタマイズを行なうこともできます。ただしこちらに書かれていることは守る必要があります。