手動で作った既存 S3 バケットを `cdk import` で CDK 管理下に取り込んでみた
製造ビジネステクノロジー部の小林です。
「コンソールでポチポチ作ったリソース、あとから CDK 管理に移したい」——運用していると出てくる要望です。CDK には既存リソースを取り込む手段がいくつかありますが、今回は cdk import を使って、手動作成した S3 バケットを CDK 管理下に移す一連の流れを実際に検証しました。
そもそも CDK は既存リソースを取り込めるのか?
用途別に 3 つの方法があります。
| 目的 | 手段 |
|---|---|
| 既存リソースを CDK 管理下に置きたい | cdk import または cdk deploy --import-existing-resources |
| 既存リソースを参照するだけ(管理は別) | fromXxx() メソッド(Bucket.fromBucketName() 等) |
| ネストされたスタックに取り込みたい | CloudFormation コンソール経由の手動 import(cdk import 非対応) |
fromXxx() は「参照」であって「管理」ではない点に注意です。取り込んだ上で設定変更まで行いたいなら cdk import を使います。
今回は cdk import を検証します。
検証環境
- AWS CDK CLI:
2.1018.1 - aws-cdk-lib:
2.180.0 - Node.js:
v22 - リージョン:
ap-northeast-1 cdk bootstrapは実施済み
手動で S3 バケットを作成
まず「手動で作られた既存バケット」を用意します。
- バージョニング: 有効
- デフォルト暗号化: SSE-S3 (AES256) + バケットキー
- パブリックアクセスブロック: 全ブロック
- ライフサイクルルール: 旧バージョンを 30 日で削除 + 未完了マルチパートアップロードを 7 日で中止


CDK プロジェクトを用意し、既存設定を「そのまま」再現する
cdk import の重要ポイントは、CDK コード側で既存リソースの状態を正確に再現することです。公式ドキュメントにも「指定したプロパティが実リソースの状態と一致しているかのチェックは行われない」と明記されています。ここがズレていると、import は通っても後続の cdk deploy で意図しない変更が実リソースに適用されてしまいます。
作成した S3 バケットの設定をすべてコードに落とし込みます。
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
export class CdkImportStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
/**
* 手動作成した既存バケットの設定を「そのまま」再現する。
* ここがズレていると import は通っても、後続の deploy で意図しない
* 変更が実リソースに適用されてしまう。
*/
const bucket = new s3.Bucket(this, 'ImportedBucket', {
bucketName: 's3-cdk-import-2026',
versioned: true, // バージョニング有効
encryption: s3.BucketEncryption.S3_MANAGED, // デフォルト暗号化 SSE-S3
bucketKeyEnabled: true, // バケットキー
// ライフサイクル:旧バージョンを30日で削除 + 未完了マルチパートを7日で中止
lifecycleRules: [
{
id: 'life-cycle-rule',
enabled: true,
prefix: 'life-cycle',
noncurrentVersionExpiration: cdk.Duration.days(30),
abortIncompleteMultipartUploadAfter: cdk.Duration.days(7),
},
],
});
}
}
cdk diff で「追加のみ」を確認
import オペレーションで許可されるのは「import するリソースの追加」だけです。まず cdk diff で差分がリソース追加のみになっていることを確認します。
$ cdk diff

[+](追加)だけになっていれば OK です。[~](変更)や [-](削除)が出ている場合はコードと実リソースがズレているサインなので、import に進む前に直します。
cdk import を実行
cdk import でインポートします。
cdk import

CloudFormation 側でも、バケットがスタックの管理下に入ったことを確認できます。

再現精度の検証 cdk diff とドリフト検出
コードが実リソースを正しく再現できているかを 2 つの方法で確認します。
cdk diff(差分なしが理想)
cdk diff CdkImportStack

出てくる差分が BootstrapVersion パラメータ(CDK のメタ的なパラメータ)だけで、リソースの実差分がゼロなら成功です。もしここでプロパティの差分が出ていたら、それは「コードと実リソースがズレている」=次の deploy で実リソースが書き換わってしまいます。
CloudFormation ドリフト検出
import の完了メッセージでも推奨される、ドリフト検出も実行しました。
aws cloudformation detect-stack-drift --stack-name CdkImportStack

cdk-import-1 %aws cloudformation describe-stack-drift-detection-status \
--stack-drift-detection-id <上記コマンドで取得したID>

IN_SYNC / DriftedStackResourceCount 0 件。
コードが手動バケットを正確に再現できている証拠です。
本当に CDK 管理下になったかタグを追加して deploy してみる
仕上げに、「もう CDK で変更できる」ことを確認します。コードにタグを 1 つ足して cdk deploy します。
// 検証用に1行追加
cdk.Tags.of(bucket).add("ImportedBy", "cdk-import");
cdk deploy CdkImportStack --require-approval never

実バケットのタグを確認すると、追加した ImportedBy=cdk-import に加えて、CloudFormation の管理タグ(aws:cloudformation:*)も自動付与されていました。


手動で作ったバケットが、完全に CDK(CloudFormation)管理下に入りました 🎉
もうひとつの選択肢:cdk deploy --import-existing-resources
比較的新しく、cdk deploy にも --import-existing-resources オプションが追加されています。こちらは、合成したテンプレート内に「同一アカウントの既存の未管理リソースと同じカスタム名を持つリソース」があれば、新規デプロイと同時に暗黙的に importしてくれるものです。CloudFormation の ImportExistingResources パラメータを利用しています。
おわりに
手動で作った S3 バケットを、データを一切失うことなく cdk import で CDK 管理下に移せました。ポイントは何度も出てきた通り「既存の状態をコードで正確に再現すること」です!cdk diff とドリフト検出で IN_SYNC を確認するところまでをワンセットにすると安心ですね。
次回は、セキュリティグループ・IAM ロール・EBS など関連リソースが絡む EC2 の import にも挑戦してみたいと思います。



