CDKのBootstrapをカスタマイズしてみた
目次
はじめに
本記事は、クラウドビルダーズ株式会社のアドベントカレンダー2024の25日目の記事となります!
こんにちは、CloudBuildersのsugawaraです。
以前の記事では、cdk bootstrapコマンドを実行することで自動デプロイされるAWSリソースを一つずつみていきました。コマンド一つで必要なリソースが作成され、CDKのデプロイが実行できる環境にできました。
今回はデフォルトの実行環境をブートストラップするのではなく、好きなようにカスタマイズしていきたいと思います!カスタマイズには、以下の2つの方法があります。
- CDK CLIを利用した簡単なカスタマイズ
- Bootstrapテンプレートを利用した詳細なカスタマイズ
それぞれ実際に利用してみて、簡単に紹介していきます。
なお、デフォルトで作成されるリソースについて確認したい方は、下記のリンクをご参照ください。
CDK CLI
名前の通り、CDKのCLIコマンド実行時にカスタマイズする方法です。cdk bootstrapコマンドにオプションを指定することで、簡単にカスタマイズすることができます。今回はよく使われそうなものをいくつかやってみます。
スタック名の変更
cdk bootstrapコマンドを実行すると、デフォルトではCDKToolkitという名前のスタックが作成されます。しかし、オプション–toolkit-stack-nameをつけることで、スタック名を変更することが可能です。
$ cdk bootstrap aws://XXXXXXXXXXXX/ap-northeast-1 \
--toolkit-stack-name CustomCDKToolkit
上記コマンドを実行することで、下記のようにスタックが作成されます。
S3バケット名の変更
ブートストラップ時に自動作成されるS3バケットは、CloudFormationテンプレートやLambdaのソースコードなどを格納します。このS3バケットの名前は、デフォルトで全アカウント共通のcdk-{Qualifier}-assets-{Account-ID}-{Region}という命名規則のもと作成されます。
例)cdk-hnb659fds-assets-XXXXXXXXXXXX-ap-northeast-1
先日CDKの脆弱性が発表されたため、デフォルトの名前ではなく、プロジェクトごとに指定したほうがセキュリティ上良いかと思われます。オプション–bootstrap-bucket-nameをつけることで、S3バケット名を変更することが可能です。
$ cdk bootstrap aws://XXXXXXXXXXXX/ap-northeast-1 \
--bootstrap-bucket-name custom-s3-bucket-20241223
上記コマンドを実行することで、下記のようにリソースが作成されます。
リソースへのタグ付け
CDKのブートストラップ時に作成されるスタックやIAMロールなどにタグ付けが可能です。今度はCustomCDKToolkitスタックとそのリソースにタグ付けしていきます。
$ cdk bootstrap aws://XXXXXXXXXXXX/ap-northeast-1 \
--toolkit-stack-name CustomCDKToolkit \
--bootstrap-bucket-name custom-s3-bucket-20241223 \
--tags SampleKey=SampleValue --profile local
CustomCDKToolkitスタックには下記のようなタグが追加されました。
また、S3バケットにもタグが追加されているのがわかります。
他にもスタックの削除保護やKMSによる暗号化などもCDK CLIで設定が可能です。また、次節のブートストラップテンプレートの変更でもCDK CLIは利用します。詳しくは、下記の公式ドキュメントをご参照ください。
https://docs.aws.amazon.com/cdk/v2/guide/ref-cli-cmd-bootstrap.html
こちらはコマンド実行時にオプションで調整するため、設定の自由度やカスタマイズ性は低いです。ユースケースは特定の箇所のみの少しのカスタマイズが必要な場合になるかと思います。
Bootstrap Template
次に、cdk bootstrapコマンドを実行したときに利用されるBootstrapテンプレートをカスタマイズする方法を紹介します。
デフォルトテンプレート
デフォルトで使用されているテンプレートを確認するには、下記のコマンドのどちらかを実行します。
# ターミナルに出力
$ cdk bootstrap --show-template
# bootstrap-template.ymlに出力
$ cdk bootstrap --show-template > bootstrap-template.yml
実行すると、下記のような出力になります。
※とても長いため詳細は必要に応じてご参照ください。
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"
InputPermissionsBoundary:
Description: Whether or not to use either the CDK supplied or custom permissions boundary
Default: ""
Type: String
UseExamplePermissionsBoundary:
Default: "false"
AllowedValues:
- "true"
- "false"
Type: String
BootstrapVariant:
Type: String
Default: "AWS CDK: Default Resources"
Description: Describe the provenance of the resources in this bootstrap stack. Change this when you customize the template. To prevent accidents, the CDK CLI will not overwrite bootstrap stacks with a different variant.
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
ShouldCreatePermissionsBoundary:
Fn::Equals:
- "true"
- Ref: UseExamplePermissionsBoundary
PermissionsBoundarySet:
Fn::Not:
- Fn::Equals:
- ""
- Ref: InputPermissionsBoundary
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
- kms:TagResource
- kms:UntagResource
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
LifecycleConfiguration:
Rules:
- Id: CleanupOldVersions
Status: Enabled
NoncurrentVersionExpiration:
NoncurrentDays: 30
- Id: AbortIncompleteMultipartUploads
Status: Enabled
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 1
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:
ImageTagMutability: IMMUTABLE
LifecyclePolicy:
LifecyclePolicyText: |
{
"rules": [
{
"rulePriority": 1,
"description": "Untagged images should not exist, but expire any older than one year",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 365
},
"action": { "type": "expire" }
}
]
}
RepositoryName:
Fn::If:
- HasCustomContainerAssetsRepositoryName
- Fn::Sub: ${ContainerAssetsRepositoryName}
- Fn::Sub: cdk-${Qualifier}-container-assets-${AWS::AccountId}-${AWS::Region}
RepositoryPolicyText:
Version: "2012-10-17"
Statement:
- Sid: LambdaECRImageRetrievalPolicy
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action:
- ecr:BatchGetImage
- ecr:GetDownloadUrlForLayer
Condition:
StringLike:
aws:sourceArn:
Fn::Sub: arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:*
FilePublishingRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:TagSession
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- 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:TagSession
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- 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:TagSession
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- 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*
- s3:GetEncryptionConfiguration
- s3:List*
- s3:DeleteObject*
- s3:PutObject*
- s3:Abort*
Resource:
- Fn::Sub: ${StagingBucket.Arn}
- Fn::Sub: ${StagingBucket.Arn}/*
Condition:
StringEquals:
aws:ResourceAccount:
- Fn::Sub: ${AWS::AccountId}
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:TagSession
Effect: Allow
Principal:
AWS:
Ref: AWS::AccountId
- 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
- cloudformation:RollbackStack
- cloudformation:ContinueUpdateRollback
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
- cloudformation:GetTemplateSummary
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
- ssm:GetParameters
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}
PermissionsBoundary:
Fn::If:
- PermissionsBoundarySet
- Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${InputPermissionsBoundary}
- Ref: AWS::NoValue
CdkBoostrapPermissionsBoundaryPolicy:
Condition: ShouldCreatePermissionsBoundary
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Statement:
- Sid: ExplicitAllowAll
Action:
- "*"
Effect: Allow
Resource: "*"
- Sid: DenyAccessIfRequiredPermBoundaryIsNotBeingApplied
Action:
- iam:CreateUser
- iam:CreateRole
- iam:PutRolePermissionsBoundary
- iam:PutUserPermissionsBoundary
Condition:
StringNotEquals:
iam:PermissionsBoundary:
Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
Effect: Deny
Resource: "*"
- Sid: DenyPermBoundaryIAMPolicyAlteration
Action:
- iam:CreatePolicyVersion
- iam:DeletePolicy
- iam:DeletePolicyVersion
- iam:SetDefaultPolicyVersion
Effect: Deny
Resource:
Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
- Sid: DenyRemovalOfPermBoundaryFromAnyUserOrRole
Action:
- iam:DeleteUserPermissionsBoundary
- iam:DeleteRolePermissionsBoundary
Effect: Deny
Resource: "*"
Version: "2012-10-17"
Description: Bootstrap Permission Boundary
ManagedPolicyName:
Fn::Sub: cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
Path: /
CdkBootstrapVersion:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name:
Fn::Sub: /cdk-bootstrap/${Qualifier}/version
Value: "25"
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
カスタムテンプレート
さきほど出力したデフォルトのブートストラップテンプレートをベースに、custom-bootstrap-template.ymlという名前のカスタムテンプレートを作成します。
変更点は、自動作成されるリソースの命名規則の変更です。具体的には、hnb659fdsという共通のQualifierが利用されていますが、これをcustomに修正します。下記は修正箇所になります。
Description: This stack includes resources needed to deploy AWS CDK apps into this environment
Parameters:
...
Qualifier:
Description: An identifier to distinguish multiple bootstrap stacks in the same environment
Default: custom # デフォルト値 hnb659fds を修正
Type: String
AllowedPattern: "[A-Za-z0-9_-]{1,10}"
ConstraintDescription: Qualifier must be an alphanumeric identifier of at most 10 characters
...
下記のコマンドで、カスタマイズしたテンプレートを使用してブートストラップを実行します。
$ cdk bootstrap aws://XXXXXXXXXXXX/ap-northeast-1 \
--toolkit-stack-name CustomCDKToolkit \
--template custom-bootstrap-template.yml
上記コマンドを実行することで、下記のようにスタックが作成されます。作成されたIAMなどのリソース物理名がcdk-customから始まっていることが確認できます。今回はQualifierだけを修正しましたが、作成されるIAMロールやポリシーなどもカスタマイズ可能です。
ブートストラップテンプレートをカスタマイズするため、設定の自由度が高いです。IAM関連のカスタマイズが可能なため、セキュリティ要件が厳しい場合などがユースケースになると思われます。
おわりに
今回はCDKの初期設定で実行されるcdk bootstrapコマンドを、CDK CLIとカスタムテンプレートを用いてカスタマイズしてみました。これまでデフォルトのリソース名やテンプレートを利用していましたが、必要に応じて柔軟にそれらを設定していきたいと思います。
2つの方法を紹介しましたが、お手軽に特定のリソース名やタグを変更したい場合にはCDK CLIを利用し、セキュリティ要件が厳しいケースや、IAMロールやポリシーの詳細な調整が必要な場合にはカスタムテンプレートを用いる方法が適しているとか思われます。
ぜひ活用してみてください!