皆さん、こんにちは! おすすめの牛は短角牛、ITエンジニアのSkyfox(なかやま)です!
この記事を読んで、AWS CloudFormationを使ってくださると嬉しいです!
この記事について
対象者
- 手作業でAWS環境構築するのに疲れた方
- CloudFormationに興味がある方
- AWSリソースをマネージドコンソールで作成したことがある方
本記事のゴール
- CloudFormationの概要がわかること
- CloudFormationを使用してみようかという気持ちになること
背景
AWS環境をマネージドコンソールで作成したことがある皆さん、こんなことを思ったことはありませんか?
今回の記事では、このようなお悩みを解決します。
CloudFormationの概要
AWS CloudFormationとは
AWS CloudFormationは、AWSのインフラ構成をコードで作成・管理してくれるサービスです。
いわば、あなたの作業チームの
「 インフラ構築・管理をしてくれる、 もう1人のメンバー 」
です!
メリット・デメリット
メリット
-
インフラ構成をコード化できる
CloudFormationを使用すると、AWSリソースの設定をコードとして管理できます。
これにより、リソースの構成が管理しやすくなり、誰でも同じ環境を構築することができるようになります。
-
作業効率がUPする
インフラ構成をコード化してしまえば、複数のAWSリソースを一度に自動で作成、更新、削除することができます。
手動の設定作業が不要になるため、作業効率が大幅に上がります。
-
環境・用途ごとに柔軟に対応できる
AWSリソースを作成するとき、開発環境や本番環境などに合わせて、リソースの設定をすることができます。
-
変更履歴を管理できる
リソースの更新や変更履歴がCloudFormationで管理できるため、誰が何を変更したかがわかるようになっています。
そのため、問題が起きたときに原因を特定しやすくなります。
デメリット
-
エラーメッセージがわかりにくい
コード側でエラーが発生したとき、エラーメッセージがわかりにくく、原因を特定することが難しいことがあります。
-
コード化には慣れが必要
コードを書くルールがあるため、CloudFormationを使い始めた方だと、はじめはコード作成に慣れが必要です。
(最近は身近なAIもあるので、簡単な構成であれば、コードを書かずにできるやも)
-
複雑なコードにすると読みづらい
コード化するときに内容が複雑になると、読みづらく、保守が難しくなることがあります。
-
デプロイに時間がかかることがある
多くのリソースを管理している場合、コードの変更やリソースの削除に時間がかかることがあります。
CloudFormationを使用するための前知識
前章までで、CloudFormationの概要や良さは、わかったかと思います。
それでは、実際にみなさんが使えるようになるため、ここからは必要な知識をインプットしていきましょう!
主なキーワード
-
テンプレート
- リソースの設定や構成など、インフラ構成に必要な情報を定義するファイル
- YAML形式 or JSON形式で書きます
- ※前章まで「コード化」と言っていたのは、これのことです
-
スタック
- テンプレートをもと作成されたAWSリソースのコレクション(集合体)
- スタック単位でリソースの作成・更新・削除をおこない、一括管理ができます
- ※テンプレートをもとに作成されたリソースたちを、まとめて管理する単位としても呼ばれています
-
変更セット
- スタックを更新する前に、その内容をプレビューする機能
- どのリソースが追加・更新・削除されるかを一目で確認できます
リソース作成までの流れ
流れはたったの3ステップです。
- テンプレートの作成
- デプロイ(スタックの作成)
※AWS マネージドコンソール or CLI - スタックをもとに設定されたAWSリソースが自動的に生成
それでは、詳しくみていきましょう!
テンプレートの書き方
覚えておきたい5セクション
テンプレートを作るときは、作りたいシステム構成を思い描いてから作りましょう!
今回はyaml形式で書いていきます。
テンプレートは、以下の7つのセクションで構成されています。
重要なのは、赤枠がついた5つです。
- Parameters
- ユーザーがスタック作成時に入力する値を設定するセクション
- スタックを作成・更新する度に設定値を変えたい場合に便利です
- Mappings
- 3階層「Key, Key, Value」で、マップ定数を定義するセクション
- 開発環境・本番環境などの環境によって、異なる値を設定したい場合に便利です
- 「Parameters」や「Conditions」セクションと組み合わせて使われます
- Conditions
- リソースや設定値の作成条件を定義するセクション
- IF分岐する場合などに使います
- ▶︎ ある環境ではリソースを作成し、他の環境では作成しないといった柔軟な設定ができます
- Resources
- 実際に作成・管理するAWSリソースを記入するセクション
- メインとなるセクションで、テンプレートには必須で書きます
- Outputs
- スタック外(別のテンプレート)にリソース情報をアウトプットするセクション
- 例えば、Aスタックで作成したS3バケットを、Bスタックで使いたいときに便利です
テンプレート例
必要なセクションについて分かったところで、実際のテンプレートを見てみましょう。
今回のテンプレートは、1回のデプロイでLowCost環境、もしくはHighPerformance環境を立ち上げる構成になっています。
dev環境・prod環境の違いは以下の通りです!
-
共通基盤:
- 1つのVPC(CIDR: 10.0.0.0/16)に構築
- パブリックサブネットを使用し、インターネットゲートウェイを通じて外部接続を確立
- SSH(ポート22)とHTTP(ポート80)のアクセスを全世界から許可
-
環境ごとの違い:
- 低コスト環境(LowCost):
- 低コストを重視
- インスタンスタイプ: t2.micro、動的パブリックIP使用
- 高性能環境(HighPerformance):
- 高性能を重視
- インスタンスタイプ: t2.large、固定のElastic IP使用
- 低コスト環境(LowCost):
# [SPEC] テンプレートのフォーマットバージョン
AWSTemplateFormatVersion: '2010-09-09'
# [SPEC] テンプレートの説明
Description: 'CloudFormation Template for Network and EC2 with Environment Parameter, Mappings, and Conditions'
# [SPEC] パラメータの定義
Parameters:
# [SPEC] 環境タイプ
EnvironmentType:
Type: String
Default: 'LowCost'
AllowedValues:
- LowCost
- HighPerformance
Description: 'Environment type (LowCost or HighPerformance)'
# [SPEC] マッピングの定義
Mappings:
# [SPEC] 環境タイプに応じた設定値のマッピング
EnvConfigMap:
LowCost:
InstanceType: 't2.micro' # [SPEC] 低コスト環境用のインスタンスタイプ
CidrBlock: '10.0.2.0/24' # [SPEC] 低コスト環境用のCIDRブロック
HighPerformance:
InstanceType: 't2.medium' # [SPEC] 高性能環境用のインスタンスタイプ
CidrBlock: '10.0.1.0/24' # [SPEC] 高性能環境用のCIDRブロック
# [SPEC] 条件の定義
Conditions:
# [SPEC] 環境が高性能環境かどうかの条件
IsHighPerformanceEnvironment: !Equals [!Ref EnvironmentType, 'HighPerformance']
# [SPEC] リソースの定義
Resources:
# [SPEC] VPCの作成
PracticeVpc:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: '10.0.0.0/16' # [SPEC] 固定のCIDRブロック
Tags:
- Key: Purpose
Value: Practice
# [SPEC] インターネットゲートウェイの作成
PracticeIgw:
Type: 'AWS::EC2::InternetGateway'
Properties:
Tags:
- Key: Purpose
Value: Practice
# [SPEC] インターネットゲートウェイをVPCにアタッチ
AttachIgwToVpc:
Type: 'AWS::EC2::VPCGatewayAttachment'
Properties:
VpcId: !Ref PracticeVpc # [SPEC] アタッチするVPCの参照
InternetGatewayId: !Ref PracticeIgw # [SPEC] インターネットゲートウェイの参照
# [SPEC] パブリックサブネットの作成
PracticePublicSubnet:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref PracticeVpc # [SPEC] サブネットを作成するVPCの参照
CidrBlock: !FindInMap [EnvConfigMap, !Ref EnvironmentType, CidrBlock] # [SPEC] 環境に基づいたCIDRブロック
AvailabilityZone: !Select [0, !GetAZs ''] # [SPEC] AZの取得
MapPublicIpOnLaunch: true # [SPEC] パブリックIPの自動割り当て
Tags:
- Key: Purpose
Value: Practice
# [SPEC] ルートテーブルの作成
PracticeRouteTable:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref PracticeVpc # [SPEC] ルートテーブルを作成するVPCの参照
Tags:
- Key: Purpose
Value: Practice
# [SPEC] ルートテーブルとIGWの関連付け
RouteTableToIgw:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId: !Ref PracticeRouteTable # [SPEC] ルートを設定するルートテーブルの参照
DestinationCidrBlock: '0.0.0.0/0' # [SPEC] 宛先CIDRブロック
GatewayId: !Ref PracticeIgw # [SPEC] InternetGatewayの参照
# [SPEC] サブネットとルートテーブルの関連付け
SubnetRouteTableAssociation:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref PracticePublicSubnet # [SPEC] サブネットの参照
RouteTableId: !Ref PracticeRouteTable # [SPEC] ルートテーブルの参照
# [SPEC] EC2のセキュリティグループの作成
PracticeEc2SecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: 'SecurityGroup for EC2' # [SPEC] セキュリティグループの説明
VpcId: !Ref PracticeVpc # [SPEC] セキュリティグループを作成するVPCの参照
SecurityGroupIngress: # [SPEC] インバウンドルール
- IpProtocol: 'tcp' # [SPEC] プロトコル
FromPort: 22 # [SPEC] 開始ポート
ToPort: 22 # [SPEC] 終了ポート
CidrIp: '0.0.0.0/0' # [SPEC] CIDR
- IpProtocol: 'tcp'
FromPort: 80
ToPort: 80
CidrIp: '0.0.0.0/0'
Tags:
- Key: Purpose
Value: Practice
# [SPEC] Elastic IPの作成(高性能環境のみ)
PracticeEip:
Type: 'AWS::EC2::EIP'
Condition: IsHighPerformanceEnvironment # [SPEC] 高性能環境の場合にのみ作成
Properties:
Domain: vpc # [SPEC] VPCに紐付け
# [SPEC] EC2インスタンスの作成
PracticeEc2Instance:
Type: 'AWS::EC2::Instance'
Properties:
InstanceType: !FindInMap [EnvConfigMap, !Ref EnvironmentType, InstanceType] # [SPEC] 環境に基づいたインスタンスタイプ
SubnetId: !Ref PracticePublicSubnet # [SPEC] サブネットの参照
ImageId: 'ami-00c79d83cf718a893' # [SPEC] 固定のAMI ID
Tags:
- Key: Name # [SPEC] EC2インスタンスの名前
Value: 'practice-ec2'
- Key: Purpose
Value: Practice
# [SPEC] EIPをEC2インスタンスにアタッチ(高性能環境のみ)
AttachEipToEc2:
Type: 'AWS::EC2::EIPAssociation'
Condition: IsHighPerformanceEnvironment # [SPEC] 高性能環境の場合にのみアタッチ
Properties:
InstanceId: !Ref PracticeEc2Instance # [SPEC] EC2インスタンスの参照
EIP: !Ref PracticeEip # [SPEC] EIPの参照
# [SPEC] 出力
Outputs:
InstanceId: # [SPEC] 出力名
Description: 'ID of the EC2 instance' # [SPEC] 出力の説明
Value: !Ref PracticeEc2Instance # [SPEC] 出力する値
PublicIP:
Description: 'Public IP of the EC2 instance'
Value: !GetAtt PracticeEc2Instance.PublicIp
スタック(AWSリソース)のデプロイ方法
今回は、一例として前章のテンプレートを使用し、AWSマネージドコンソールでデプロイする方法を簡単に書きます。
前章のテンプレートを使用する場合は、事前にコードを貼り付けた、「PracticeStack.yaml」ファイルを作成してください!
ステップ1
CloudFormationのコンソールを開き、「スタックの作成」の「新しいリソースを使用(標準)」(画像の赤枠)をクリックします。
ステップ2
「スタックの作成」ステップでは、今回すでに作成してあるテンプレートを使いたいので、画像のように設定していきます。
テンプレートの設定は、「テンプレートの指定」項目の「ファイルの選択」ボタン(画像の赤枠)をクリックし、指定します。
ステップ3
「スタックの詳細を指定」ステップでは、以下の設定をします。
- 設定
- スタック名を提供
- スタック名: ※適したスタック名をつけてください
- パラメータ
- ※ テンプレートの内容により変化します
- テンプレートの「Parameters」セクションで設定した項目が表示されます
- ここで今回作成したいスタックの設定値を選択していきます
- ※ テンプレートの内容により変化します
- スタック名を提供
注意
前章のテンプレートを使用している方は、LowCost環境とHighPerformance環境で、コストが異なるので注意です!
ステップ4
「スタックオプションの設定」ステップでは、適宜設定します。
ステップ5
「確認して作成」ステップで、設定した項目を確認し、大丈夫でしたら、「送信」ボタンをクリックします。
ステップ6
画像のように、CloudFormationと作成したリソースが以下のように確認できましたら、完成です。
Appendix
変更セットについて
今回は詳細には書きませんが、スタック更新時に以下の赤枠のように、変更があるリソースを「変更セットのプレビュー」項目で表示してくれます。
これで変更した内容が合っているか確認してから、スタックを更新することができます。
(「間違って必要なリソースを消してしまった」ということも防げます。)
さいごに
AWS CloudFormationのイメージは、つきましたでしょうか?
この記事を導入としてもらい、
AWSリソースを一括作成・管理する
「 インフラ構築・管理をしてくれる、 もう1人のメンバー 」
として、AWS CloudFormationで快適なインフラ構築を実施してもらえればと思います。
使用イラスト
- イラスト「Loose Drawing」