kakakakakku blog

Weekly Tech Blog: Keep on Learning!

AWS CDK の cdk import コマンドを使って既存リソースをインポートする

AWS CDK の cdk import コマンドを使って既存リソースをインポートする(取り込む)手順を試してみた❗️何かしらの理由があって Infrastructure as Code (IaC) に組み込めず,そのままプロダクションにリリースされてしまうということもあると思う.

Amazon S3 バケットと Amazon CloudWatch Logs ロググループ

今回は比較的シンプルな構成として,Amazon S3 バケットと Amazon CloudWatch Logs ロググループをインポートをする.実際の現場ではもっと多くのリソースをインポートしたいという場面もあるとは思うけど...!

まずはマネジメントコンソールを使って以下のように設定しておく👌

  • Amazon S3 バケット
    • バケット名: kakakakakku-sandbox-cdk-import
    • バージョニング: 有効
  • Amazon CloudWatch Logs ロググループ
    • ロググループ名: kakakakakku-sandbox-cdk-import
    • 保持期間: 7日間
    • ログクラス: 低頻度アクセス

Amazon CloudWatch Logs ロググループのログクラス(低頻度アクセス)に関しては以下の記事も参照してもらえればと💡

kakakakakku.hatenablog.com

Step.1

まずは AWS CDK でインポート用のスタックを作る.

👾 sandbox-cdk-import-stack.ts

import {
    Stack,
    StackProps,
} from 'aws-cdk-lib'
import { Construct } from 'constructs'

export class SandboxCdkImportStack extends Stack {
    constructor(scope: Construct, id: string, props?: StackProps) {
        super(scope, id, props)
    }
}

一度スタックをデプロイしておく✔️

$ cdk deploy SandboxCdkImportStack

AWS CloudFormation: SandboxCdkImportStack スタック

Step.2

次に Amazon S3 バケットと Amazon CloudWatch Logs ロググループの設定を確認しつつ,AWS CDK で同じように実装する.removalPolicy は必ず RemovalPolicy.RETAIN にしておく.ちなみに今回は通常のプロパティ以外に bucketNamelogGroupName も設定しているけど,AWS CDK のドキュメントを読むとリソース名は設定しないことが推奨と書かれていたりする📝このあたりはチームの戦略によるところかなーと.

We usually recommend to not include resource names into your AWS CDK resource definitions so that it becomes easier to deploy your resources multiple times.

docs.aws.amazon.com

👾 sandbox-cdk-import-stack.ts

import {
    RemovalPolicy,
    Stack,
    StackProps,
    aws_logs,
    aws_s3,
} from 'aws-cdk-lib'
import { Construct } from 'constructs'

export class SandboxCdkImportStack extends Stack {
    constructor(scope: Construct, id: string, props?: StackProps) {
        super(scope, id, props)

        new aws_s3.Bucket(this, 'SandboxCdkImportBucket', {
            bucketName: 'kakakakakku-sandbox-cdk-import',
            versioned: true,
            removalPolicy: RemovalPolicy.RETAIN
        })

        new aws_logs.LogGroup(this, 'SandboxCdkImportLogGroup', {
            logGroupName: 'kakakakakku-sandbox-cdk-import',
            retention: aws_logs.RetentionDays.ONE_WEEK,
            logGroupClass: aws_logs.LogGroupClass.INFREQUENT_ACCESS,
            removalPolicy: RemovalPolicy.RETAIN
        })
    }
}

そして cdk import コマンドを実行する.リソース名を省略する場合はリソース名を入力するようにプロンプトが表示されるけど,今回はリソース名を設定しているため yes/no を入力するようにプロンプトが表示された.どちらも yes にしておく.

$ cdk import SandboxCdkImportStack
SandboxCdkImportStack
SandboxCdkImportStack/SandboxCdkImportBucket/Resource (AWS::S3::Bucket): import with BucketName=kakakakakku-sandbox-cdk-import (yes/no) [default: yes]? yes
SandboxCdkImportStack/SandboxCdkImportLogGroup/Resource (AWS::Logs::LogGroup): import with LogGroupName=kakakakakku-sandbox-cdk-import (yes/no) [default: yes]? yes
SandboxCdkImportStack: importing resources into stack...
SandboxCdkImportStack: creating CloudFormation changeset...

 ✅  SandboxCdkImportStack
Import operation complete. We recommend you run a drift detection operation to confirm your CDK app resource definitions are up-to-date. Read more here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/detect-drift-stack.html

すると以下のようにインポートできた✔️

AWS CloudFormation: SandboxCdkImportStack スタック

Step.3

cdk import コマンドの実行時に We recommend you run a drift detection operation to confirm your CDK app resource definitions are up-to-date. というログが出ているため,AWS CloudFormation のドリフト検出機能を実行しておく.今回は設定項目も少なく,1発で IN_SYNC(ドリフトなし)になった.

AWS CloudFormation: SandboxCdkImportStack スタック(ドリフト検出結果)

注意点としては AWS CloudFormation のドリフト検出機能は対象リソースが限られているため,ドリフト検出結果が IN_SYNC だとしても,必ずしも「完全一致」になっているとは言えない可能性があるというところ🚨

docs.aws.amazon.com

Step.4

最後はインポートしたリソースを変更する.今回は Amazon CloudWatch Logs ロググループの保管期間を aws_logs.RetentionDays.ONE_WEEK(7日間) から aws_logs.RetentionDays.ONE_MONTH(1ヶ月間) に変更する.

👾 sandbox-cdk-import-stack.ts

import {
    RemovalPolicy,
    Stack,
    StackProps,
    aws_logs,
    aws_s3,
} from 'aws-cdk-lib'
import { Construct } from 'constructs'

export class SandboxCdkImportStack extends Stack {
    constructor(scope: Construct, id: string, props?: StackProps) {
        super(scope, id, props)

        new aws_s3.Bucket(this, 'SandboxCdkImportBucket', {
            bucketName: 'kakakakakku-sandbox-cdk-import',
            versioned: true,
            removalPolicy: RemovalPolicy.RETAIN
        })

        new aws_logs.LogGroup(this, 'SandboxCdkImportLogGroup', {
            logGroupName: 'kakakakakku-sandbox-cdk-import',
            retention: aws_logs.RetentionDays.ONE_MONTH,
            logGroupClass: aws_logs.LogGroupClass.INFREQUENT_ACCESS,
            removalPolicy: RemovalPolicy.RETAIN
        })
    }
}

そして cdk diff コマンドと cdk deploy コマンドを実行して,期待通りに Amazon CloudWatch Logs ロググループの保管期間を変更できた✔️

$ cdk diff SandboxCdkImportStack
Stack SandboxCdkImportStack
Resources
[~] AWS::Logs::LogGroup SandboxCdkImportLogGroup SandboxCdkImportLogGroupD75F1BC6 
 └─ [~] RetentionInDays
     ├─ [-] 7
     └─ [+] 30


✨  Number of stacks with differences: 1

$ cdk deploy SandboxCdkImportStack

✨  Synthesis time: 2.66s

(中略)

 ✅  SandboxCdkImportStack

✨  Deployment time: 22.23s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:000000000000:stack/SandboxCdkImportStack/d36b1dd0-b9f6-11ee-9501-0ee3eafa3ebd

✨  Total time: 24.89s

AWS CloudFormation: SandboxCdkImportStack スタック

まとめ

AWS CDK の cdk import コマンドを使って既存リソースをインポートする(取り込む)手順を試してみて,流れを把握できたのは良かった❗️もちろんプロダクション環境などに影響を出さずにリソースを新しく作り直せる(差し替えられる)なら AWS CDK で作り直した方が良いとは思うけど,どうしてもインポートが必要なステートフルなリソースもあると思う.そういうときに今回の cdk import コマンドを検討したいと思う👌

関連記事

aws.amazon.com