AWS-CloudFormation

CloudFormation IaCジェネレーターで既存AWSリソースをCFnにインポートしてみた

はじめに

こんにちは、omkです。

いよいよ、n年前から欲しかったあの機能がリリースされましたね。
IaCジェネレータではCFn外で作成したリソースをCFnにインポートするためのテンプレートをリソースに合わせて作成してくれます。
インポート自体は前々から出来ましたが実リソースをスキャンして設定値を吸い出してくれる点が本機能のありがたポイントですね。

すでに何番煎じかですがの記事ですが私の方でもまとめていきます。ブログなんてなんぼあってもいいですからね。

やってみた

以降、コンソールを利用してやっていきます。
CFnのナビゲーションペインに「IaCジェネレーター」が追加されていますね。

IaCジェネレーターはおおよそ以下の4工程で使用出来ます。

  1. 既存リソースのスキャンを行う
  2. スキャンされたリソースを選択してCFnテンプレートを作成する
  3. (必要に応じて作成されたテンプレートを修正する)
  4. 作成されたテンプレートを使用してCFnにインポートする

それではリソースのスキャンからしていきます。

スキャン

IaCジェネレーターの画面から「新しいスキャンを開始」を押すだけです。
最大10分かかることがあるとコンソールにも記載がありますがまぁまぁ時間がかかります。

スキャン後に追加されたリソースの利用には際スキャンが必要となります。

テンプレートの作成

スキャンが完了したらテンプレートを作成します。
これも基本的には「テンプレートを作成」を押して必要なリソースを選択していくだけです。
リソースの検索方法にも色々あるので絞り込みが容易ですね。

特に便利だと感じたのが「スキャンしたリソースを追加」の画面ですべてのリソースを追加しなくても次の「関連するリソースを追加」の画面で関連リソースをまとめて出してくれる点です。

例えばVPCのネットワーク周り全部をテンプレートに含みたいとして、「スキャンしたリソースの追加」の画面では対象のVPCだけを選択するとします。

そしたらVPCのサブネットやルートテーブル、VPC上のEC2インスタンスなど関連するリソースを一覧してくれるわけです。
その中で必要なものだけを取捨選択していけば欲しいリソースだけを構築するテンプレートが出来るので大変簡単です。

こんな感じでテンプレートが作成されました。
リソース間の参照も論理IDでRefしてくれています。

LambdaやAPIGatewayではテンプレートに読み込めない内容があるようです。
AWS::Lambda::Function リソースの更新
AWS::ApiGateway::RestAPI リソースの更新

その場合の設定値は基本的にパラメータで設定するようにテンプレートを作成してくれます。
IaC ジェネレーターと書き込み専用プロパティ

テンプレートの修正

今回はとりあえず修正は無しで進めます。
(テンプレートに書き込み専用プロパティが存在しないとこの場では修正出来ない??)

スタックのインポート

作成されたテンプレートを使用してインポートしていきます。
テンプレート上で削除ポリシーが「DELETE」になっている場合は、インポート後にテンプレートの誤りに気づいてスタックを削除した場合や操作自体を誤ってスタックを消してしまった場合など、一緒にリソースも消えてしまうので注意です。

掃除に使っている記事もあって面白いなと思いました。これも便利ですね。
IaC ジェネレーターで豪快にリソースを掃除した話

作成されたテンプレートで「スタックにインポート」を選択して通常のCFnスタックの作成と同じ流れでリソースをインポートしていきます。

影響範囲の確認も欠かさず実施します。

作成されたテンプレートで変更無しにリソースをインポート出来ました。
CFnにインポートして管理用のタグをつけてるための更新を行っているみたいですね。

CFnで更新してみた

作成されたテンプレートをダウンロードしてVPCのネームタグを変更してみました。

◯変更前

  EC2VPC00vpc0dbfb733a9c4c444a00fzZia:
    UpdateReplacePolicy: "Retain"
    Type: "AWS::EC2::VPC"
    Properties:
    (略)
      Tags:
      - Value: "omukai-vpc"
        Key: "Name"

◯変更後

  EC2VPC00vpc0dbfb733a9c4c444a00fzZia:
    UpdateReplacePolicy: "Retain"
    Type: "AWS::EC2::VPC"
    Properties:
    (略)
      Tags:
      - Value: "omk-vpc"
        Key: "Name"

通常通りスタックを更新します。
問題なく変更されました。

これで今後はリソースをCFnで管理更新していけますね。

おまけ

何個かどういう挙動をするか動作検証をしてみたので以下に記載していきます。

論理IDは変更可能か

可能でした。

作成されるテンプレートの論理IDはリソースタイプの「AWS::${1}::${2}」に沿って「${1}${2}${ランダムな文字列}」の構成になっています。
ベストプラクティス的には名前に意味を持たせるのはあんまりかもしれませんが同じリソースタイプが複数ある場合にどれがどれなのでまぁ変えてしまいたいですね。

というわけでコンソールに「論理IDを編集」というボタンがありました。

対象リソースの論理IDと合わせて参照先指定の論理IDも直してくれるのでそのままテンプレートを使用すれば動きます。

インポート時に書き込み専用プロパティのパラメータで指定した内容に応じてリソースが変更されるか

以下の内容で検証した場合には変更されませんでした。
RDSのパスワードとかなら変わるかもです。

検証1: Lambdaの「Code/S3Bucket」「Code/S3Key」の指定

Lambdaを対象としてみたところ、Lambdaのパッケージが所在する「S3バケット」と「オブジェクトキー」をそれぞれパラメータに要求されるようになりました。

テキトーなLambdaで確認したところこんな感じになっていました。

Parameters:
  LambdaFunction00omkfunc00yytUFCodeS3BucketOneOfqYP8d:
    NoEcho: "true"
    Type: "String"
    Description: "An Amazon S3 bucket in the same AWS-Region as your function. The\
      \ bucket can be in a different AWS-account.\nThis property can be replaced with\
      \ other exclusive properties"
  LambdaFunction00omkfunc00yytUFCodeS3KeyOneOf4UOzg:
    NoEcho: "true"
    Type: "String"
    Description: "The Amazon S3 key of the deployment package.\nThis property can\
      \ be replaced with other exclusive properties"

Resources:
  LambdaFunction00omkfunc00yytUF:
    UpdateReplacePolicy: "Retain"
    Type: "AWS::Lambda::Function"
    DeletionPolicy: "Retain"
    Properties:
      (略)
      Code:
        S3Bucket:
          Ref: "LambdaFunction00omkfunc00yytUFCodeS3BucketOneOfqYP8d"
        S3Key:
          Ref: "LambdaFunction00omkfunc00yytUFCodeS3KeyOneOf4UOzg"

もしこのパラメータで指定するS3オブジェクトのコードが既存のコードと異なる内容であった場合にLambda関数で使用するコードに変更が発生するか確認します。

◯元のコード

import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

◯変更したコード

import json

# コメントを追記

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

コメントを追加しました。
これをZipにかためてS3にアップし、パラメータに指定してインポートしてみます。

結論変わりませんでした。

同じテンプレート・パラメータ・S3オブジェクトでスタックを更新してみました。
変わりませんでした。

検証2: Lambdaの「Code/ZipFile」の指定

先の例でパラメータでパスを指定するのではなく、CFnテンプレートに「Code/ZipFile」に変更するコード内容を直書きしてインポートしてみました。
変わりませんでした。
置き換えポリシーをDELETEにしてみても特に変わりなくでした(新しい関数も作成されず)。

おわりに

IaCジェネレーター機能で既存リソースをCFnに取り込んでみました。
リソースの管理はIaCでやりたいものの、手で作ったほうが楽なタイミングはやっぱりどうしても発生してしまうのでこういった機能が救いになりますね。

以上、最後までお付き合いありがとうございました。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA