既存のS3バケットをCDKの管理下にインポートする

既存のS3バケットをCDKの管理下にインポートする

今回は cdk import を使って、CDKスタックの管理下にS3バケットを取り込もうと思います。
Clock Icon2024.08.15

データ事業本部の笠原です。

現在我々のチーム内ではServerless FrameworkからAWS CDKやAWS SAMへ移行するプロジェクトが多いです。

Serverless Frameworkで定義したAWSリソースを、CDKやSAMで再定義するのですが、S3バケットやRDSインスタンス等削除されては困るリソースについては、 DeletionPolicy: Retain 等をしておいてから、Serverless Frameworkのスタックを削除すればリソースはそのまま残りますが、このままではCDKスタックの管理下にはありません。

今回はCDKスタックの管理下にS3バケットを取り込もうと思います。
ちなみに、CDKには既存リソースを参照する from で始まるメソッドがたくさんありますが、これらはリソースを参照するだけでCDKスタックの管理下にはなりませんので、今回は使用しません。

3行まとめ

  • cdk import で既存リソースを取り込める
  • プロパティは既存リソースの設定に合わせる
  • DeletionPolicy の設定は必須

構成図

今回はまずServerless FrameworkでS3バケットを1つ作成しておきます。

arch1

その後、Serverless Frameworkのプロジェクトを削除し、S3バケットをそのまま残します。

arch2

最後に、AWS CDKにて残ったS3バケットをCDKスタックの配下にインポートします。

arch3

Serverless FrameworkでS3バケットを作成する

まずはS3バケットを作成します。
S3バケットを作成するためだけにServerless Frameworkを使うことは普通しませんが、今回はServerless Framework移行の検証も兼ねて、Serverless Framework V3にて、S3バケットを1つ作成します。

serverless.yml は以下のようにします。
S3バケットとバケットポリシーを定義しています。S3バケットに対して DeletionPolicy: Retail とすることで、 sls remove してもS3バケットだけはそのまま残るようにします。

serverless.yml
serverless.yml 48
service: sls-s3-migration-test
frameworkVersion: '3'
configValidationMode: error

provider:
  name: aws
  stage: ${env:ENV, 'dev'}
  region: ap-northeast-1
  deploymentBucket:
    name: ${self:service}-deploy-bucket

resources:
  Resources:
    # S3
    Bucket:
      Type: AWS::S3::Bucket
      DeletionPolicy: Retain
      Properties:
        BucketName: ${self:service}-bucket-${self:provider.stage}
        PublicAccessBlockConfiguration:
          BlockPublicAcls: true
          BlockPublicPolicy: true
          IgnorePublicAcls: true
          RestrictPublicBuckets: true
        BucketEncryption:
          ServerSideEncryptionConfiguration:
            - ServerSideEncryptionByDefault:
                SSEAlgorithm: "AES256"
    BucketPolicy:
      Type: AWS::S3::BucketPolicy
      Properties:
        Bucket:
          Ref: Bucket
        PolicyDocument:
          Statement:
            - Sid: AllowSSLRequestsOnly
              Action:
                - "s3:*"
              Effect: "Deny"
              Resource:
                - Fn::Join:
                    - ""
                    - - "arn:aws:s3:::"
                      - Ref: Bucket
                - Fn::Join:
                    - ""
                    - - "arn:aws:s3:::"
                      - Ref: Bucket
                      - "/*"
              Principal: "*"
              Condition:
                Bool:
                  "aws:SecureTransport": "false"

serverless.yml ができたら、デプロイしましょう。

デプロイ
sls deploy

これで、S3バケットが1つできました。

create_bucket

Serverless Frameworkプロジェクトを削除して、S3バケットだけ残す

デプロイしたばかりですが、プロジェクトを削除します。

削除
sls remove

削除後、S3バケットは DeletionPolicy: Retain の設定のためそのまま残ります。なお、バケットポリシーには設定していなかったので、バケットポリシーは削除されています。

CDKでS3バケットを管理下に置く

今度はAWS CDKを扱います。
まずは、CDKのプロジェクトを作成します。

CDKプロジェクト作成
npx cdk init --language typescript

続いて、適当なスタックを作成します。
ここでは、S3バケットを取り込むために、
既存のバケット名や設定に合わせて記載します。

lib/s3-migration-test-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';

export class S3MigrationTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'Bucket', {
      bucketName: 'sls-s3-migration-test-bucket-dev',
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
      encryption: s3.BucketEncryption.S3_MANAGED,
      removalPolicy: cdk.RemovalPolicy.RETAIN,
    });
  }
}

スタックを定義したら、以下のコマンドで取り込みます。

CDKにインポート
npx cdk import

途中で確認事項が表示されます。
バケット名があっていれば、 yes を入力しましょう。

確認
S3MigrationTestStack/Bucket/Resource (AWS::S3::Bucket): import with BucketName=sls-s3-migration-test-bucket-dev (yes/no) [default: yes]? yes

Import operation complete. と表示されれば、CDKの管理下にS3バケットが入りました。

あとは、 sls remove 時に削除されたバケットポリシーをCDKで再定義してあげると良いでしょう。

まとめ

今回は cdk import を使って、既存リソースをCDKの管理下に取り込む方法を示しました。
CDKで既存リソースを管理したい場合に、有用な手段です。

この記事が参考になれば、幸いです。

参考

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.