NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

注目のタグ

    コンソール派必見!CloudFormationデビューガイド~テンプレートってどうやって書くの?~

    本記事は  IaCウィーク  1日目の記事です。
    ⚙️  告知記事  â–¶â–¶ æœ¬è¨˜äº‹ â–¶â–¶  2日目  ðŸ’»

    はじめに

    こんにちは、入社2年目のインフラエンジニアの中村です!

    本記事は、IaCウィークの中でも「超初学者向け」として、AWS CloudFormation(※以下CloudFormation)に初めて触れる方に向けた内容となっています。 私が初めて CloudFormation を使ってリソース作成に挑戦した際の経験談を交えながら、CloudFormation の基本的な仕組みと、私を救ってくれたチームメンバー作の”CloudFormation 神テンプレート”をもとに、テンプレートの基本的な書き方を解説していきます。
    ※本記事ではテンプレートの書き方にフォーカスしており、スタックのデプロイ手順などの内容は含まれていません。

    「CloudFormationって難しそう…コンソールでやった方が絶対早いんじゃん…」 なんて思っていた私ですが、このテンプレートのおかげで理解が進み、IaCの世界に一歩踏み出すことができました。 その感動を、少しでもお伝えできたら嬉しいです!

    ☁️ CloudFormationって何?コンソール操作と何が違うの?

    AWSでリソースを作成するとなって真っ先に思いつくのが、AWSコンソールを利用した方法です。 コンソール操作は、分かりやすいUIでポチポチ操作できるので、初心者でも比較的簡単にAWSリソースを作成することができます。
    でも、こんなことを思ったことはありませんか?

    「毎回同じ設定を手動でやるのは面倒くさい…」
    「設定ミスが起きやすいし、再現性がない…」
    「チームで共有したいけど、どうやってやるの?」

    そこで登場するのが AWS CloudFormation です。

    🔧 CloudFormationの概要

    CloudFormationは、AWSのリソース構成をコード(テンプレート)で定義できるサービスです。 具体的には、インフラの設計図をYAMLやJSON形式で記述し、それをもとにAWSが自動的にリソースを構築してくれる仕組みです。 テンプレートには、作成したいリソースやその設定内容を記述します。 それを「スタック」としてデプロイすることで、AWSがその設計図通りにリソースを構築してくれます。

    💡 余談ですが… 構文がシンプルで読みやすく、コメントも書けるため、個人的にはYAML形式をおすすめします。

    🆚 CloudFormationとコンソール操作との違い
    項目 マネジメントコンソール CloudFormation
    操作方法 手動でポチポチ コードで定義
    再現性 手動操作のため再現が困難 テンプレートで完全再現可能
    自動化 手動操作が中心 CI/CDと連携可能
    共有 スクリーンショットや手順書 テンプレートファイルで簡単共有
    バージョン管理 変更履歴の管理が困難 Gitなどで履歴管理可能

    ⚔️CloudFormationとの対峙

    さて、ここからは私がCloudFormationに初挑戦した際の体験談をお話しします。

    私はとあるプロジェクトで、検証環境の構築を任されることになりました。 初日の目標はセキュリティグループ(※以下SG)の作成だったのですが、結果的にほぼ丸一日を費やしても成果ゼロ。 何度もテンプレートを修正してはエラーに悩まされ、スケジュール遅延の不安から、コンソールでの作成に切り替えることにしました。

    すると、ものの5分でSGが完成。 「やっぱりコンソールの方が早いじゃん…」と、正直CloudFormationに嫌気がさしてしまいました。

    しかし、すでに「CloudFormationで作ります!」とチームメンバーに宣言してしまっていた手前、他のリソースまでコンソールでポチポチ作るわけにはいきません。 そこで、チームメンバーに助けを求めたところ、“CloudFormation神テンプレート”を授けていただいたのです。

    👼神テンプレート構成解説

    いよいよ、”CloudFormation神テンプレート”のご紹介です。
    このテンプレートは、各種リソース毎の、あらゆる要件に対応できるよう汎用化されたCloudFormationテンプレートです。 それぞれのテンプレートには、リソース毎に必要な設定値がすべて記載されており、要件に応じてパラメータを入力していくだけで、テンプレートが完成するという非常に便利な代物になっています。

    業務で使用しているテンプレートは公開できないため、この神テンプレートをベースに作成した、中村作のSG用テンプレートを参考に、CloudFormationテンプレートの構成について解説していきます。
    今回紹介するSG用テンプレートの設定は以下の通りです。

                                   
    項目内容
    Descriptionsample
    VPCパラメータで指定したVPC
    インバウンドルール①インターネット全体(0.0.0.0/0)からHTTPS(ポート443)を許可
    インバウンドルール②パラメータで指定した別のセキュリティグループからHTTPS(ポート443)を許可
    アウトバウンドルールインターネット全体(0.0.0.0/0)へのHTTPS(ポート443)通信を許可
    通信プロトコルtcp または udp(パラメータで選択)
    Nameタグパラメータで入力した任意の環境名(例: dev)・システム名(例: webapp)を組み合わせた名前(例: dev-webapp-sg)

    さて、ここからはテンプレートの具体的な中身を見ていきます。
    このテンプレートは、大きく分けて下記4つの要素に分かれています。

    ①基本項目

    AWSTemplateFormatVersion: 2010-09-09
    Description: 'Create SecurityGroup'

    CloudFormation テンプレートのフォーマットバージョンと、テンプレートの説明です。 どちらも 必須ではありませんが、記述しておくことでテンプレートの構成が明確になり、用途の把握もしやすくなります。 とりあえず、冒頭に記載しておくことをおすすめします。

    ②Metadataセクション(UI設定)

    Metadata:
      AWS::CloudFormation::Interface:
        ParameterGroups:
          - Label:
              default: 'Common Parameters'
            Parameters:
              - EnvName
              - SystemName
          - Label:
              default: 'SecurityGroup Parameters'
            Parameters:
              - VpcId
              - IpProtocol

    このセクションでは、CloudFormationコンソール上でパラメータを入力する際のUI表示を整えることができます。

    本セクションはリソースの作成には直接影響しないため、本記事では詳細な解説は割愛しますが、上記テンプレートでは、SystemName や EnvName といった汎用パラメータと、SGの設定値となるパラメータとで、表示を分けるような記述となっています。

    ③Resourceセクション(パラメータの反映)

    Resources:
      InstanceSecurityGroup:
        Type: 'AWS::EC2::SecurityGroup'
        Properties:
          GroupDescription: sample
          VpcId: !Ref VpcId
          SecurityGroupIngress:
            - IpProtocol: !Ref IpProtocol
              FromPort: 443
              ToPort: 443
              CidrIp: 0.0.0.0/0
        - IpProtocol: !Ref IpProtocol
              FromPort: 443
              ToPort: 443
              SourceSecurityGroupId: !Ref SourceSecurityGroupId
          SecurityGroupEgress:
            - IpProtocol: !Ref IpProtocol
              FromPort: 443
              ToPort: 443
              CidrIp: 0.0.0.0/0        
          Tags:
            - Key: Name
              Value: !Sub '${EnvName}-${SystemName}-sg'

    このセクションでは、定義したパラメータをリソースの設定に反映させます。CloudFormation テンプレートの中でも、このResources セクションが最も重要な部分であり、極端に言えばこのセクションだけでテンプレートを構成することも可能です。後述する Parameters セクションも必須ではありません。

    では、なぜ Parameterセクションを使うのか?
    それは、テンプレートの可変部分を変数化するためです。

    もちろん、リソース名や設定値をテンプレート内に直接記述することもできます。しかし、全く同じ構成のスタックを複数作成するケースは稀であり、環境ごとに異なる値を使いたい場面が多くあります。
    そのため、可変部分をパラメータとして定義し、スタック作成時に値を外部から渡すことで、再現性を保ちつつ柔軟な運用が可能になります。

    パラメータの参照方法

    テンプレート内でパラメータを参照するには、!Ref や !Sub という構文を使用します。 これらの構文の後に、Parameters セクションで定義したパラメータ名を指定することで、外部から渡された値をリソース設定に反映できます。
    上記テンプレートの場合、EnvName・SystemName・VpcId・IpProtocol・SourceSecurityGroupIdの5つを変数化しています。スタックをデプロイする際、手動の場合は下記画像のようにAWS コンソール上の UI で入力、CI/CD の場合はテンプレートに対して明示的にパラメータを渡すことで設定されます。

    💡!Ref と !Sub の違い

       
    項目説明
    !Ref 他のリソースやパラメータの値をそのまま参照する際に使用。
    !Sub 文字列の中に変数を埋め込む際に使用。
    例えば "${EnvName}-${SystemName}-sg" のように記述することで、パラメータ値を含む文字列を生成できる。

    ④Parametersセクション(パラメータの定義)

    Parameters:
    # ----------------------- 'Common Parameters' -----------------------
      EnvName:
        Description: Environment_Name
        Type: String
      SystemName:
        Description: System_Name
        Type: String
    # ----------------------- 'SecurityGroup Parameters' -----------------------
      VpcId:
        Description: Vpc_ID_(select)
        Type: 'AWS::EC2::VPC::Id'
      IpProtocol:
        Default: 'tcp'
        Description: IpProtocol_(select)
        Type: String
        AllowedValues:
          - 'tcp'
          - 'udp'
     SourceSecurityGroupId:
        Description: SourceSecurityGroup_ID_(select)
        Type: 'AWS::EC2::SecurityGroup'

    このセクションでは、スタック作成時に外部から渡すパラメータについて定義します。
    ここで定義できる内容は様々ありますが、今回は上記テンプレートで使用している Default、Description、Type、AllowedValues の 4 つの項目について解説します。

                       
    項目説明
    Defaultパラメータの初期値。よく使う値を設定しておくことで、入力の手間やミスを減らせる。
    Descriptionパラメータの説明文。スタック作成時に AWS コンソール上で表示され、入力内容が分かりやすくなる。
    Type入力値の型を指定する。任意の文字列を入力させる文字列型(String)や 、既存のAWSリソースの中から選択させるAWS リソース型(例:AWS::EC2::VPC::Id)などがある。
    AllowedValues入力可能な値を制限する。誤入力を防ぎ、選択肢を明確にできる。

    解説まとめ

    以上がCloudFormationテンプレートの解説になります。
    今回はSG用のテンプレートを例にご紹介しましたが、この構成は他の AWS リソースにも転用可能です。AWS の公式ドキュメントには、各リソースに対応した CloudFormation の設定項目が詳細に記載されているため、それらを参考にしながらテンプレートに落とし込んでいくイメージです。

    実際、私が参考にした神テンプレートには SG用のテンプレートはありませんでしたが、他のリソースのテンプレートをベースに、自力で作成することができました。
    基本構成を理解することで、他のリソースへの応用はもちろん、1つのテンプレートで複数のリソースをまとめて作成するなど、より柔軟で高度なテンプレート設計が可能になるかと思います。

    さいごに

    ここまでCloudFormationの利点とその使い方についてお話しましたが、決してコンソール操作が悪だということはありません。 実際、私が所属するチームでは、コンソールポチポチ作業の方が圧倒的に多いです。
    また、IaCには今回ご紹介したCloudFormationだけでなく、TerraformやCDKなど、さまざまな手段があります。

    「必ずしもこれを使うのが良い」などといったことはなく、その時々に合わせた適切な手段を用いることがベストです。 今持っている手段に固執せず、好奇心を持って新しい技術に飛び込む姿勢を持つことができたら、「できるITエンジニア」にぐっと近づくのではないでしょうか。 これを読んでくれた方の新たな一歩に、少しでも貢献できていたら嬉しいです。

    執筆者:中村真琴 気持ちは新人 インフラエンジニア