はじめに
2024/2/6に発表された情報で、IaC generatorにおいて、コンソールで作成した既存のAWS環境をスキャンして、cdkへ変換できるようになりました。
https://aws.amazon.com/jp/blogs/news/import-entire-applications-into-aws-cloudformation/
何がすごいのか
- コンソールで作成したAWS環境を、CDKを使用したコードに変換することができる
- コンソールで作成したAWS環境をコード管理することができる
コンソールで作成したS3をコード化&追加で変更してみた
今回は、新規でS3バケットを作成し、ライフサイクルポリシーを設定しているリソースをスキャンしてCDK化します。CDKをデプロイし、既存リソースのS3と同期します。リソースとCDKが同期したら、CDKにライフサイクルの設定を追記し、再度デプロイを行い、既存のS3バケットにCDKで作成したリソースが追加されるかを試します。
ポイント
- タグキーを使用して、スキャンしたいリソースを絞る
読み取りリソースの数が多いとエラーとなってしまうので、
リソースにタグ(key, value)を設定し、cdkに変換するコマンドで、設定したkeyを指定します。
今回は、
key=migrate-cdk,
value=test
にしました。
前提条件
CDバージョン: v2.126.0
CDK バージョン確認
cdk --version
私の場合は、2.116.1と古かったので、下記のコマンドでアップデートしました。
npm install -g aws-cdk
S3バケットをコンソールで作成
CLIでコードを変換
cdk migrate --language typescript --from-scan new --stack-name cdk-migrate-test-s3 --filter tag-key=migrate-cdk
実行結果
✅ Scan Complete!mental feature and development on it is still in progress. We make no guarantees about the outcome or stability of the functionality.
Using the latest successful scan which is 0 days, 0 hours, and 7 minutes old.
Applying filters to resource scan.wait, this can take 10 minutes or longer.
finding related resources.
Found 1 resources.
Generating CFN template from scanned resources.
Please wait, template creation in progress. This may take a couple minutes.
[CREATE_IN_PROGRESS] Template Creation in Progress
Template successfully generated!
⏳ Generating CDK app for cdk-migrate-test-s3...
Applying project template app for typescript
Initializing a new git repository...
・
(中略)
・
Executing npm install...
✅ All done!
⚠️ Some resources could not be migrated completely. Please review the README.md file for more information.
変換が完了しました。私の場合は、約30分かかりました。
CloudFormationのIaCジェネレータにテンプレートが作成され、
cdk-migrate-test-s3というフォルダと、CDKのファイル群が生成されます。
変換されたコードがこちらになります。
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
export interface CdkMigrateTestS3StackProps extends cdk.StackProps {
}
export class CdkMigrateTestS3Stack extends cdk.Stack {
public constructor(scope: cdk.App, id: string, props: CdkMigrateTestS3StackProps = {}) {
super(scope, id, props);
// Resources
const s3Bucket00testmigratecdkscans300yPmn6 = new s3.CfnBucket(this, 'S3Bucket00testmigratecdkscans300yPMN6', {
publicAccessBlockConfiguration: {
restrictPublicBuckets: true,
ignorePublicAcls: true,
blockPublicPolicy: true,
blockPublicAcls: true,
},
bucketName: 'test-migrate-cdk-scan-s3',
ownershipControls: {
rules: [
{
objectOwnership: 'BucketOwnerEnforced',
},
],
},
bucketEncryption: {
serverSideEncryptionConfiguration: [
{
bucketKeyEnabled: true,
serverSideEncryptionByDefault: {
sseAlgorithm: 'AES256',
},
},
],
},
lifecycleConfiguration: {
rules: [
{
status: 'Enabled',
id: 'test-1year',
prefix: '/test',
noncurrentVersionExpiration: {
noncurrentDays: 30,
},
expirationInDays: 364,
},
],
},
versioningConfiguration: {
status: 'Enabled',
},
tags: [
{
value: 'test',
key: 'migrate-cdk',
},
],
});
s3Bucket00testmigratecdkscans300yPmn6.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.RETAIN;
}
}
cdk diffで比較してみます。
cdk diff
実行結果
Stack cdk-migrate-test-s3
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Could not create a change set, will base the diff on template differences (run again with -v to see the reason)
Parameters and rules created during migration do not affect resource configuration.
Parameters
[+] Parameter BootstrapVersion BootstrapVersion: {"Type":"AWS::SSM::Parameter::Value<String>","Default":"/cdk-bootstrap/hnb659fds/version","Description":"Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"}
Conditions
[+] Condition CDKMetadata/Condition CDKMetadataAvailable: {"Fn::Or":[{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"af-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ca-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-northwest-1"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-3"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"il-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"me-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"me-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"sa-east-1"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-2"]}]}]}
Resources
[+] AWS::S3::Bucket S3Bucket00testmigratecdkscans300yPMN6 S3Bucket00testmigratecdkscans300yPMN6
Other Changes
[+] Unknown Rules: {"CheckBootstrapVersion":{"Assertions":[{"Assert":{"Fn::Not":[{"Fn::Contains":[["1","2","3","4","5"],{"Ref":"BootstrapVersion"}]}]},"AssertDescription":"CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."}]}}
✨ Number of stacks with differences: 1
CDKをデプロイ
cdk deploy
実行結果
CDKとAWS環境を同期することができました。
✨ Synthesis time: 6.31s
cdk-migrate-test-s3: creating stack for resource migration...
cdk-migrate-test-s3: importing resources into stack...
cdk-migrate-test-s3: creating CloudFormation changeset...
cdk-migrate-test-s3 | 0/2 | 9:25:33 | IMPORT_IN_PROGRESS | AWS::CloudFormation::Stack | cdk-migrate-test-s3 User Initiated
cdk-migrate-test-s3 | 0/2 | 9:25:35 | IMPORT_IN_PROGRESS | AWS::S3::Bucket | S3Bucket00testmigratecdkscans300yPMN6 Resource import started.
cdk-migrate-test-s3 | 0/2 | 9:25:38 | IMPORT_IN_PROGRESS | AWS::S3::Bucket | S3Bucket00testmigratecdkscans300yPMN6
cdk-migrate-test-s3 | 1/2 | 9:25:39 | IMPORT_COMPLETE | AWS::S3::Bucket | S3Bucket00testmigratecdkscans300yPMN6 Resource import completed.
cdk-migrate-test-s3 | 1/2 | 9:25:41 | UPDATE_IN_PROGRESS | AWS::S3::Bucket | S3Bucket00testmigratecdkscans300yPMN6 Apply stack-level tags to imported resource if applicable.
cdk-migrate-test-s3 | 0/2 | 9:26:06 | UPDATE_COMPLETE | AWS::S3::Bucket | S3Bucket00testmigratecdkscans300yPMN6
cdk-migrate-test-s3 | 1/2 | 9:26:08 | IMPORT_COMPLETE | AWS::CloudFormation::Stack | cdk-migrate-test-s3
✅ cdk-migrate-test-s3
✨ Resource migration time: 42.24s
✅ cdk-migrate-test-s3
✨ Resource migration time: 42.24s
cdk-migrate-test-s3: applying CDKMetadata and Outputs to stack (if applicable)...
cdk-migrate-test-s3: start: Building 4110a55191e1b6658121e64fb4f2dd5aab310d58df30f23bababfe8cc69f352d:current_account-current_region
cdk-migrate-test-s3: success: Built 4110a55191e1b6658121e64fb4f2dd5aab310d58df30f23bababfe8cc69f352d:current_account-current_region
cdk-migrate-test-s3: start: Publishing 4110a55191e1b6658121e64fb4f2dd5aab310d58df30f23bababfe8cc69f352d:current_account-current_region
cdk-migrate-test-s3: success: Published 4110a55191e1b6658121e64fb4f2dd5aab310d58df30f23bababfe8cc69f352d:current_account-current_region
cdk-migrate-test-s3: deploying... [1/1]
✅ cdk-migrate-test-s3 (no changes)
✨ Deployment time: 0.15s
変換したCDKコードにライフサイクルを追記
下記が追加したCDKになります。
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
export interface CdkMigrateTestS3StackProps extends cdk.StackProps {
}
export class CdkMigrateTestS3Stack extends cdk.Stack {
public constructor(scope: cdk.App, id: string, props: CdkMigrateTestS3StackProps = {}) {
super(scope, id, props);
// Resources
const s3Bucket00testmigratecdkscans300yPmn6 = new s3.CfnBucket(this, 'S3Bucket00testmigratecdkscans300yPMN6', {
publicAccessBlockConfiguration: {
restrictPublicBuckets: true,
ignorePublicAcls: true,
blockPublicPolicy: true,
blockPublicAcls: true,
},
bucketName: 'test-migrate-cdk-scan-s3',
ownershipControls: {
rules: [
{
objectOwnership: 'BucketOwnerEnforced',
},
],
},
bucketEncryption: {
serverSideEncryptionConfiguration: [
{
bucketKeyEnabled: true,
serverSideEncryptionByDefault: {
sseAlgorithm: 'AES256',
},
},
],
},
lifecycleConfiguration: {
rules: [
{
status: 'Enabled',
id: 'test-1year',
prefix: '/test',
noncurrentVersionExpiration: {
noncurrentDays: 30,
},
expirationInDays: 364,
},
{
status: 'Enabled',
id: 'test-1year-hoge',
prefix: '/hoge',
noncurrentVersionExpiration: {
noncurrentDays: 30,
},
expirationInDays: 364,
},
],
},
versioningConfiguration: {
status: 'Enabled',
},
tags: [
{
value: 'test',
key: 'migrate-cdk',
},
],
});
s3Bucket00testmigratecdkscans300yPmn6.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.RETAIN;
}
}
ライフサイクルを追加したCDKをテンプレートに変換
cdk synth
デプロイでライフサイクルを追加
cdk deploy
実行結果
「test-1year-hoge」という、ライフサイクルを追加することができました。
感想
過去にコンソールで作成した環境は、CDK化して管理することをあきらめていましたが、既存環境をスキャンしてCDK化できるようになったので、CDKで管理・運用できる幅が広がったので、正直この機能は誕生して嬉しかったです。CDKのスキャンで、どこまでコードと実環境が同期できるのか、今後も様々なパターンを試してみます。