11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS CloudFormation IaCジェネレータの使用感と注意点

Last updated at Posted at 2024-02-24

IaCジェネレータとは

AWSの既存リソースをもとにCloudFormationのテンプレートを作成してくれるサービスです。
これまで手動構築したAWSリソースをもとにIaCテンプレートを作成するには、サードパーティ製のツールを使う必要がありましたが、この度AWSの公式機能として公開されました。
作った環境をそのまま別アカウントに移行したい時や管理外のリソースをスタックにインポートして管理したい時などには大変便利な機能ですね。

そんな注目のIaCジェネレータですが、実際に使ってみて個人的に感じたことがあるので残しておきたいと思います。

IaCジェネレータでテンプレートを生成する

スキャン対象

今回は手動で作成した以下の構成に対して、IaCジェネレータを使ってテンプレート化を試してみました。

構成自体は特に本筋と関係がなく、これくらいの規模で試した感想であることが伝わればと思います。

手順

WebコンソールからIaCジェネレータを利用します。

  1. WebコンソールからCloudFormationを開く。メニューから「IaCジェネレータ」をクリック。
    2024-02-18-18-08-18.png

  2. 「新しいスキャンを開始」をクリック。クリックすると以下のようにスキャンの進捗バーが表示されます。
    2024-02-18-18-09-21.png

  3. 今回のリソースでは3分ほどでスキャンが完了。リソース数は163だったようです。
    以下画面で「テンプレートを作成」をクリック。
    2024-02-18-18-12-11.png

  4. テンプレート名を入力します

    • 「削除ポリシー」「置換ポリシーを更新」は保持(デフォルト)にすると、作成テンプレートの全てのリソースにDeletionPolicy: "Retain",UpdateReplacePolicy: "Retain"が付きます。スタックの削除・更新の際にリソースも削除したい場合は削除ポリシー・置換ポリシーを削除にしておきましょう。
    • 入力したら「次へ」をクリックします。
      2024-02-18-18-12-36.png
  5. スキャンされたリソース一覧が表示されます。
    テンプレートに含みたいリソースを選択していきます。
    image.png

  6. 事前にリソースにタグが付いていれば、タグキーやタグ値で絞り込みが可能です。
    image.png

  7. 実際にタグ値(=prd)で絞り込みするとこのようになります。
    選択が完了したら「次へ」をクリックします。
    今回は前述の構成リソースにはタグ値をつけたため、こちらでおおよそ対象リソースの選択はできていると思います。
    image.png

  8. 関連リソース一覧が表示されます。

    • 選択したリソースに関連するリソースをIaC generator側で備忘的に提案してくれます。
    • ここではとりあえず提案されたものを全て選択してしまっています。NATGWにアタッチされたEIPやRouteTable内のRouteリソースなどは筆者がタグ付けを忘れていたもののため、提案が役立ちました。一方でNetworkInterfaceなどは特に不要だったのですが、デフォルトでチェック状態だったためここでは追加してしまいました。
    • 選択が終わったら「次へ」をクリックします。
      image.png
  9. 最後に確認ページが表示されます。見切れていますが右下の「テンプレートを作成」をクリック。
    image.png

  10. 少し待つとテンプレートが表示されます。
    image.png

テンプレートの作成作業は以上で完了です。非常に簡単です。

選択したリソースをそのままCloudFormaitonのスタックとして管理したい場合は「スタックにインポート」を行うとよいでしょう。

ここではアカウント移行を考えてYAMLテンプレートをダウンロードしてファイルの中身を確認していきました。
以下がテンプレートの冒頭です。
image.png
MetadataとしてTemplateIdが記載されている以外は何の変哲もありません。
Resources下のリソース論理IDには固有のIDが自動で割り振られており、画像のVPCはEC2VPC00vpc~~~とリソースタイプっぽい値とユニークIDが論理IDとなっています。

なお、テンプレートは後述の点があるため、ほとんどの場合で多少の手修正が必要になると思われます。

注意点

出力されるテンプレートが不安定

実際に出力されたテンプレートを見て、個人的に注意が必要だと思った点を挙げておこうと思います。

1. リソース間の参照に物理IDが使われることがある

テンプレート内のリソース間参照にはテンプレート内の論理IDを利用してほしい所ですが、物理IDで参照していることがあり、注意が必要です。

例えば、以下はELBリソースの定義箇所ですが、SecurityGroupsで指定されているセキュリティグループIDが物理IDのハードコードとなっています。
image.png

他にもサブネットの定義箇所でもVpcIdで指定されているVPCIDが物理IDのハードコードです。
image.png

既存リソースを既存アカウントのスタックにインポートし管理する場合は気にならないかもしれませんが、
別アカウントへの移行などで新規環境構築にこのテンプレートを使う場合には物理IDではエラーとなるため、手修正する必要があります。

一方で、論理IDを利用出来ている箇所も当然あります。以下はVPC Endpointの定義箇所ですが、VpcIdにはRef関数を使って自動生成されたVPCの論理IDを参照できています。
image.png

物理IDと論理IDの参照がどう使い分けられているかはわかりませんが、少なくともばらつきがあることは認識しておくとよいでしょう。

2. DeletionPolicy、UpdateReplacePolicyのデフォルト設定がRetainである

前述の作成手順でも記載しましたが、WebコンソールのIaCジェネレータでテンプレートを作成する際は更新置換ポリシー:保持削除ポリシー:保持がデフォルト設定になっています。
したがって、テンプレートの内部では全てのリソースに対して、以下の画像のようにUpdateReplacePolicy: "Retain"DeletionPolicy: "Retain"が挿入されることになります。
image.png
この設定ではスタックを削除した場合にもリソースがそのまま保持され、スタックを更新した際にもリソースは置換されず新たに作られます。

一方で、CloudFormationを一から手動で書く際に、UpdateReplacePolicyDeletionPolicyを指定しなかった場合は、どちらもDeleteがデフォルトです。

CloudFormationのテンプレート作成に慣れている人がデフォルトでDelete設定であることを期待して、WebコンソールのIaCジェネレータでデフォルト設定でテンプレートを作成するとRetainとなるという、デフォルト設定に対するギャップがあるので注意が必要です。

3. Cfnのリソース記述ルールに従わない場合がある

そのままテンプレートを使うとエラーとなるリソース設定がありました。

以下の画像はRouteの定義です。IaCジェネレータで出力されたテンプレートでは、赤線のGatewayIdVpcEndpointIdが指定されています。
image.png
このGatewayIdVpcEndpointIdは、Routeリソースにはどちらか一方しか定義できません。両方指定しているとスタック作成時にエラーとなります。また、VpcEndpointIdで指定されているのはインターネットゲートウェイの物理IDであって、VPCエンドポイントのIDではないのでこれも誤りです。このRouteの本来の定義は、VpcEndpointIdが無いものとなる筈です。

他にも同様のエラーがあります。以下はELBのListenerRuleの定義です。
image.png
ここではルーティングの設定としてField: "path-pattern"が設定されています。そしてパラメータとしてValuesPathPatternConfigが設定されていますが、このテンプレートをそのまま使うとValidationErrorとなります。
なぜならField: "path-pattern"の場合、設定できるのはValuesPathPatternConfigのどちらか一方のみだからです。

どちらの例も、設定できない値を設定してしまうというエラーが起きています。これらのエラーは実際にスタック作成時にはValidationErrorとして検出されます。CloudTrailで当該リクエストの箇所を見れば詳細なエラーが確認できるのでデバッグ自体は簡単ですが注意が必要です。

4. 不要なリソースを作成することがある

正確な挙動は理解できていないのですが、スタック作成時にAlready Existエラーで失敗するリソースがありました。

以下の画像はRouteの定義です。
image.png
前述のGatewayIdVpcEndpointIdの両指定問題もあるのですが、これは一旦おいておきます。
ここのリソースでIaCジェネレータが作成しようとしているのはVPCのIPブロック内を送信先とするlocalへのルート定義です。しかし、このRouteの紐付け先であるRouteTableリソースは、作成時にローカルルートをデフォルトで作成するようで、個別にローカルルートのRouteリソースを設定する必要はありません。以上の理由で、ここではAlready Existエラーが発生してしまったものと思います。

このほかにも状況によって、エラーとならないものの冗長なリソース(リソース内で参照紐付きしているのに、Associationリソースで新たに紐付けさせようとするなど)が存在するようなので、その可能性を考慮しながらリファクタリングするとよいかもしれません。

IaCジェネレータの利用制限

公式ページに記載の通りですが、IaCジェネレータには以下のクォータが存在します。

引用元:既存のリソースのテンプレートを生成 - AWS CloudFormation

名前 名前
1 回のアカウントスキャンで処理できるリソースの最大数 100000
1 日あたりのスキャン数 (リソースが 10,000 未満のアカウントの場合) 3
1 日あたりのスキャン数 (リソースが 10,000 以上のアカウントの場合) 1
アカウントあたりの同時に生成されるテンプレートの数 5
1 回のテンプレート生成で同時にモデル化されるリソースの数 5
1 つのテンプレートでモデル化できるリソースの合計数 500

特にスキャン回数については、とりあえず試しに実行してみようと考え無しに使うとすぐ上限に達してしまいます(私のことです)。リソースが少ない小規模システムであっても、1日3回までと厳しめの設定になっているため計画的な利用が必要です。
アカウント移行や定期的なリソース変更の自動検知など、いろいろな使い方が考えられるIaCジェネレータではありますが、この制約は頭に入れたうえで移行計画やスケジュールを検討しましょう。

また、1テンプレートのリソース数は500が上限となっています。おそらくシステム全体を1テンプレートに収めようとすると上限を超えることが多くなると思います。(今回のミニマムな構成では、リファクタリングして最終的に30リソース程度になりました。)
PoCレベルのミニマムな構成を除けば、基本的にはスタックの分割方法を検討する必要があると考えておいた方がよいでしょう。

最後に

既に多くの方がやってみた記事をあげておりN番煎じですが、サンプルは多くても困らないだろうという考えで投稿してみました。
IaCジェネレータが便利なことは間違いないのですが、実際に業務で使ことになるとまだまだネットには出てきていない躓き所がありそうです。とはいえ、そのうち改善されていくとは思うのでアプデに期待ですね。
現時点では本記事であげたような制約は認識しておく必要がありますが、手動構築したリソースを公式サービスでテンプレート化することができるのは非常に安心感があり、ありがたい限りです。
現行のリソース状態をテキスト化できるという観点でみれば、流行りのLLMを活用した構成レビューなどにも応用できそうです。今後も使えるところでは積極的に使っていきたいと思います。

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?