本記事は
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用テンプレートの設定は以下の通りです。
| 項目 | 内容 |
|---|---|
| Description | sample |
| 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エンジニア」にぐっと近づくのではないでしょうか。 これを読んでくれた方の新たな一歩に、少しでも貢献できていたら嬉しいです。