インフラ

Former2を使って、既存リソースをCDK管理下においてみた

cdk

CDKの管理化に既存リソースをおきたいことがありました。
CDK管理下に置くことは、CDK書いて、CFn生成、CFnスタックインポートでできます。
しかし、リソースの数が多いと大変です。

Former2を使えば、既存リソースのCDKコード化を楽にできるため紹介します。

Former2で既存リソースからCDKのコードを作成

Former2の実行は以下の記事が参考になりました。
Former2をローカルにホストして、既存リソースのCloudFormationテンプレートを出力してみた

外部サイトにAWSの認証情報を置くのは、抵抗感があるためローカル実行できるのは嬉しいですね。

Former2を実行して、CDKのコードを生成します。

Former2で生成されるCDK修正

Former2で生成されるCDKのコードはCDK v1のみのようです。(2022/3/5時点)
v2へ変更と、デフォルトでMyStackになっているスタック名を変えます。

また、CFnインポート時に、DeleteionPolicyが必要なため追記します。

#!/usr/bin/env node
import 'source-map-support/register';
// cdk v2に変更
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';

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

      const SQSQueue = new sqs.CfnQueue(this, 'SQSQueue', {
          delaySeconds: 0,
          maximumMessageSize: 262144,
          messageRetentionPeriod: 345600,
          receiveMessageWaitTimeSeconds: 0,
          visibilityTimeout: 30,
          queueName: "import-test",
      });
      // CloudFormationインポート時に必要
      SQSQueue.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY)
  }
}

const app = new cdk.App();
new ImportCdkStack(app, 'ImportCdkStack', { env: { region: 'ap-northeast-1' } });
app.synth();

cdk synthしてCFnテンプレート作成・CFnテンプレートインポート

以下の記事と重複する箇所が多いため、こちらの記事では詳細は省略します。
AWS CDKで既存リソースをCDK管理下に置く方法

cdk synthでCFnテンプレートを生成します。
CFnテンプレートでも変更が必要な箇所があります。

CFnテンプレートに「AWS::CDK::Metadata」が含まれているとインポートが失敗するため、記述を削除してインポートします。

{
  "Resources": {
    "SQSQueue": {
      "Type": "AWS::SQS::Queue",
      "Properties": {
        "DelaySeconds": 0,
        "MaximumMessageSize": 262144,
        "MessageRetentionPeriod": 345600,
        "QueueName": "import-test",
        "ReceiveMessageWaitTimeSeconds": 0,
        "VisibilityTimeout": 30
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "ImportCdkStack/SQSQueue"
      }
    }
  },
  "Parameters": {
    "BootstrapVersion": {
      "Type": "AWS::SSM::Parameter::Value",
      "Default": "/cdk-bootstrap/hnb659fds/version",
      "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
    }
  },
  "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."
        }
      ]
    }
  }
}

CDKでインポートしたリソースを変更してみる

インポートができたら、CDKから確認してみましょう。
インポートした直後の状態でcdk diffを実行してみます。

% npm run cdk diff ImportCdkStack

> import-cdk@0.1.0 cdk /Users/satomasaki/work/src/github.com/msato0731/import-cdk
> cdk "diff" "ImportCdkStack"

Stack ImportCdkStack
There were no differences

差分が無いため、問題なさそうです。

CDKでQueueのvisibilityTimeoutを変更して、リソースに反映させてみます。

% npm run cdk diff ImportCdkStack
> import-cdk@0.1.0 cdk /Users/satomasaki/work/src/github.com/msato0731/import-cdk
> cdk "diff" "ImportCdkStack"

Stack ImportCdkStack
Resources
[~] AWS::SQS::Queue SQSQueue SQSQueue 
 └─ [~] VisibilityTimeout
     ├─ [-] 30
     └─ [+] 40

上記の状態でcdk deployを実行すると、無事に変更反映されました。

 # 変更前
aws sqs get-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789/import-test --attribute-names VisibilityTimeout                  
{
    "Attributes": {
        "VisibilityTimeout": "30"
    }
}
# 変更後
aws sqs get-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789/import-test --attribute-names VisibilityTimeout
{
    "Attributes": {
        "VisibilityTimeout": "40"
    }
}

(注意点)Former2ではCDK L1 Constructしか生成できない

現状Former2で生成できるのはL1 Constructのみです。
L2 Construct使いたい場合は、自分で書く必要があります。

生成されたL1を参考にしながら、自分でL2書くのもありだと思うため、L2使う場合もFormer2で生成する価値はあると思います。

まとめ

CloudFormerしか使ったことがなかったので、Former2の便利さに感動しました。
特に、ローカルから実行可能・UIがわかりやすい点が好きです。

既存リソースをCDK管理には、それなりにハードルがありますが、IaC管理のメリットも大きいためバランス見ながらやっていきたいと思います。

  • Former2がL2 Constructに対応していない
  • CloudFormationのインポートに対応していないリソースが割とある
datadog
CDKを使ってECSにDatadogAgentコンテナを追加して監視してみたCDKでECSにDatadogAgentコンテナを追加して、Datadog上からメトリクスを確認してみました。 ECS on Farga...
cdk
ブラウザでCDKを試せるツール「cdk-web」を使ってみたブラウザ上で、cdkを試せるツール「cdk-web」というツールがあります。 便利そうなので、ざっくり紹介します。 どんなツール? ...
【翻訳記事】AWS CDKで複数の環境を設定する4つの方法はじめに(訳者より) 本稿は以下の、ブログ記事の翻訳です。 この翻訳記事を書くことに快諾頂いた@der_rehanさんに感謝します。 ...