💡

マネコンからCFnへの切り替えでハマったポイント

2024/09/14に公開

マネコンで作成したAWSのリソースをCFnに書き換えた際の移行の仕方やハマったポイントなどを備忘録として残したいと思います。

今回移行したリソース

以下のような、よく見る定番構成をIaCで移行しました。

  • ALB
  • ECS(Fargate)
    • frontとbackを1台ずつ(+ バッチ用のスケジュールタスク)
  • RDS

マネコンからCFnへ切り替える方法

基本的にはマネコンと公式リファレンスを行ったり来たりする泥臭いやり方をしました(もっと良い方法あれば知りたい)

↓↓↓ 具体的には以下です ↓↓↓

ハマったポイント

CFnに移行する中でハマったポイントや、重要だと思う箇所をまとめます

xxxxx already exists in stack arn:aws:cloudformation:ap-northeast-1:xxxxx:stack/ECS-Console-V2-Service-xxxxx

何をしようとして起きた?

  • ECRのリポジトリを作成しようとした

原因は?

  • ECRの名前衝突
  • ECRは一意の名前にしないといけないので、既存の環境のECRと同じ名前はダメだよと言われた

対策は?

  • 似ているけど、微妙に違う名前をつけた
    • 既存の環境をIaC化してた背景もあり、元の環境は残したままリソースを作成しないといけかったので、同じ名前にできなかった

Encountered unsupported property AwsvpcConfiguration

何をしようとして起きた?

AWS::Events::RuleFARGATE用のバッチを定義したかった

原因は?

  • EcsParametersPlatformVersionを指定していない(FARGATEでは必要っぽい)

PlatformVersion
タスクのプラットフォームバージョンを指定する。1.1.0など、プラットフォームバージョンの数字部分のみを指定する。
この構造体は、LaunchTypeがFARGATEの場合のみ使用されます。有効なプラットフォームバージョンの詳細については、Amazon Elastic Container Service Developer GuideのAWS Fargate Platform Versionsを参照してください。

対策は?

  • EcsParametersPlatformVersionLATESTに設定
BatchEventXXXXX:
    Type: AWS::Events::Rule
    Properties:
      ScheduleExpression: cron(35 18 * * ? *) # 03:35 JST
      Targets:
        - Id: xxxxx
          RoleArn: arn:aws:iam::xxxxx:role/ecsEventsRole
          EcsParameters:
            TaskDefinitionArn: !Ref xxxxx
            LaunchType: FARGATE
            TaskCount: 1
+           PlatformVersion: LATEST
            NetworkConfiguration:
              AwsVpcConfiguration:
                AssignPublicIp: ENABLED
                SecurityGroups: [!ImportValue xxxxx]
                Subnets: !Ref xxxxx

IaCのレビューは負担が重いから、ちゃんと理解してコード書けヨ!!

(よくわかってないけど、何となく動いたっぽいからプルリク出そ〜っと) で出したプルリクについた先輩からお言葉を戒めとして、紹介します。懺悔です。

かなり間違ってるだろう箇所多い気がするけど、不安なとことか、なんとなくで書いてるとこないかな?
xxxx(セキュリティグループのARNをコメントなしでハードコーティングしていた箇所) とかコンソールで調べるのもかなり時間かかるし、レビュー精度は低くなるので
問題ありそうな箇所、なんとなくで書いてるとこは事前に教えて欲しいかな

ロードバランサがxxxx(拠点1)、xxxx(拠点2)、xxxx(拠点3)からのポート22(ssh接続)を許可してるけどほんとに必要?

(↑開発する拠点は一つだけなのに、複数拠点からsshできるようにする必要はなくない?という意味です)

ほんとに必要なのか、なんとなくで書いてるのか分からないので返答ください!
なんとなくな気がする。
この辺たくさんあるかも
セキュリティグループID直書きだからひとつひとつ調べるの厳しい...せめてコメント欲しいかな
xxx(セキュリティグループのID) は xxx(セキュリティグループ名) だと思うけど、既存のセキュリティグループを利用するの?
既存リソースでいう xxxxx(セキュリティグループ名) をこの Type: AWS::EC2::SecurityGroup で作ってると思うけど、中で使ってる。。循環してていろいろおかしい
ポート443はロードバランサが許可するポートで、ECSインスタンスが許可したのはフロントエンドの80とバックエンドの3000なはず
ポート3306はDBが許可するポートでいらないはず

言い方は優しいですが、多分がっかりさせちゃっただろうなと思い、めちゃくちゃ反省しました。
ごめんなさいと心で反芻しながら、修正していた記憶があります。(⇦駆け出しあるある)

私のような駆け出しの方は、このようなレビューが返ってこないように不安な箇所は事前に質問するなり、コメントするなりしましょう。

マネコンの設定が間違っているかもしれないゾ!!

一からリソースの設定を確認できるいいチャンスです!
意外と直すところがありました。以下は、私が変更したリソースの一例です。

  • 不要なポートを開けていた
    • 多分使うかも?で-1で全開放していたポートもTCPだけにしたりしました(YAGNIってやつですね)
  • RDSのMultiAZを解除した
    • 基本的にはMultiAZが望ましいですが、今回のシステムは小規模な社内システムなので、コスト面も考慮してMultiAZをなしにしました(バックアップを取るだけでも対応できそうと判断)
    • ある程度、運用した後なので、逆にリソースの設定を整理することができました。

リソースの依存関係に注意ダゾ!!

リソースを3つのファイルに分けましていましたが、リソース通しに依存関係があるので、注意しましょう。
ファイルの実行順序においては、途中でエラーになるので、注意ですmm

秘匿情報はSecretManagerを使おうヨ!!

マネコンではパスワードなども直書きで大丈夫でしたが、コードで管理する際はそういうわけにもいかないので、SecretManagerを使うと便利でした!
特にRDSなどは、AWS側でフォーマットが用意されているので、楽でした。

以下のような形で簡単に取得できるので、おすすめですmm

Value: "{{resolve:secretsmanager:xxxxx:SecretString:password}}"

Discussion