はじめに
本記事はAWSで提供されているサーバレスサービスをAWS CloudFormationと呼ばれるIaCサービスを使用して構築するハンズオンです。
AWSサーバレスアーキテクチャで文章解析サービスを構築するで作成した文章解析サービスをCloudFormationで構築できるように、CloudFormationの概要やテンプレートの基本的な使い方についてハンズオンを通して学習します。
全3記事の構成となっており、本記事は第1回となります。
- CloudFormationでAWSサーバレスアーキテクチャを構築する その1
- 近日公開 CloudFormationでAWSサーバレスアーキテクチャを構築する その2
- 近日公開 CloudFormationでAWSサーバレスアーキテクチャを構築する その3
注意①
本資料内スクショのAWS管理コンソールのデザインは資料作成当時のものです。
デザインは今後変更される可能性があり、スクショと差異がある場合がありますのでご了承ください。
注意②
今までのハンズオン(前提条件・知識に記載)で実施した手順は基本省略して記載するのでご了承ください。
複雑な手順等は例外として記載する場合があります。
注意③
ハンズオンで作成したリソースについてはハンズオン終了後、各自削除をお願いします。
ゴール
- IaC(Infrastructure as Code)のメリット、デメリットが理解できている
- AWS CloudFormationの概要が理解できている
- CloudFormationテンプレートの基本的な書き方が理解できている
- S3バケットをデプロイするCloudFormationテンプレートを作成することができる
前提条件・知識
基本ありません。
ただし、本ハンズオンはAWSサーバレスアーキテクチャで文章解析サービスを構築するで作成したサービスをCloudFormationテンプレートにします。
サービスの概要、使用しているAWSサービスについて事前に理解していただいていると、ハンズオンをスムーズに進めることができます。
CloudFormationテンプレート化する対象のサービス
冒頭で説明させていただいたように本ハンズオンはAWSサーバレスアーキテクチャで文章解析サービスを構築するで作成した文章解析サービスをCloudFormationテンプレートにします。
文章解析サービス構築の際実施した作業概要・処理概要・アーキテクチャ図を示します。
- Amazon API GatewayでAPI構築
- S3バケットにファイルをアップロードするREST API作成
- Amazon S3のバケットを構築
- 文章解析対象ファイルのアップロード先
- Amazon EventBridgeルールの構築
- S3バケットへのファイルアップロードがトリガー、ステートマシンがターゲット
- AWS Step Functionsでステートマシン構築
- S3バケットにアップロードされたファイルに記載されている日本語文章取得
- Amazon Translateで日本語文章を英語翻訳
- Amazon Comprehendで日本語文章を感情分析
- 英訳結果と感情分析結果をAmazon DynamoDBのテーブルに格納
IaC化しない場合の問題点
AWSサーバレスアーキテクチャで文章解析サービスを構築するでは、ブラウザでAWS管理コンソールにログインし、ボタンをクリックしたり、キーボードで入力するなどして開発してきました。
このような方法で作成したサービスを運用する場合や今後機能追加を行う場合では、次のケースにより問題が発生します。
複数の環境でサービスを動かすケース
以下のようなケースです。
- 障害発生時の切り分けを行いたいのでその検証を行うための環境が欲しい
- サービスに機能を追加するため、開発で使用するための環境が欲しい
この場合、次の問題が発生する可能性があります。
- サービスを新環境に再構築する必要があるが、手動で作成してきたため時間がかかる
- 手動で作成するため、ヒューマンエラーが発生する
- 新環境を構築する際の手順を管理しておく必要がある
開発効率を高めたいケース
以下のようなケースです。
- 開発のコスト効率・開発スピードを高めたい
- 環境差異を少なくし、本番環境デプロイ時の障害を少なくしたい
- 開発人数を増やして1人当たりの作業工数を少なくしたい
この場合、次の問題が発生する可能性があります。
- 「ちょっと試してみる」ということがしづらい。試したとしてもリソースを適宜削除しないとムダなコストが発生する
- 手動で新環境を作成するため、環境毎に差異が発生し、環境起因の障害につながる可能性がある
- 現在のシステムの状態・改修前と改修後の差分がわからないため、新規参入者がすぐに開発に取り掛かるのが難しく、開発スピードがすぐに上がらない
問題に対する解決策(IaCのメリット)
上記問題点を解決する方法がIaC(Infrastructure as Code)(以降、 IaC と呼ぶ)
です。
IaCとは、サーバやネットワークなどのインフラの構成をコード化
し、その構築や管理を自動化する手法です。
- コード化することで、手動での作業がなくなり、インフラ設定の変更が容易になる
- 手動構築・手動設定によるヒューマンエラーを防止でき、保守性の向上、一貫性のある環境構築ができる
- コードを再利用することでほぼ同じ環境を簡単に複製できる
- Gitなどのバージョン管理リポジトリでコードを一元管理でき、変更がいつ誰によって行われたか、変更差分などが明確になる
IaCは変化の激しい昨今のビジネス環境に追いついていくため、必須となる手法であると考えます。
実際、IaCの市場規模は2022年の8億米ドルから2027年には23億米ドルに達すると予想されています。
IaCがビジネス目標を達成する上で重要視されていることを裏付ける情報と言えます。
参考:Infrastructure as Code (IaC)の市場規模、2027年に23億米ドル到達予測
IaCのデメリット
有益と思われるIaCにもデメリットがあるのでいくつか紹介します。
-
AWS CloudFormation
などのサービスやTerraform
などのツールを導入する必要があり、これらの導入に時間がかかる - コード化やツールの学習コストがかかる
- 作成するシステムの規模が小さい場合、手動で作成した方がコストが低い可能性がある
以上のメリットデメリットを考慮してIaCの導入を検討する必要があります。
使用サービス紹介
今回ハンズオンで触るサービスについて説明します。
その他サービスについてはその都度説明いたします。
AWS CloudFormation
AWS CloudFormationとは、AWSが提供するIaCサービスです。
AWSリソースの構築とサーバ設定の自動化や構成管理を行うことができます。
CloudFormationでは、テンプレート
というYAMLやJSON形式のファイルで、サーバやネットワークなどのインフラの構成をコードとして表現します。
このサービスは2011年2月
に一般公開されました。
用語
用語 | 意味 |
---|---|
テンプレート | AWSリソースのプロビジョニングや設定を行うためのYAMLまたはJSON形式のテキストファイル。CloudFormationに当該ファイルをアップロードすることで当該処理が実行される |
スタック | テンプレートによって構築されたAWSリソースの集まりのこと。CloudFormationは作成したスタックをスタック単位で管理する |
ネスト | 一般的に「入れ子」を意味する。CloudFormationに備わっているネスト機能を使うことで複数のテンプレートを含むスタックを作成できる |
ロールバック | 一般的に「データ更新などで障害が起こったときに、その前の状態にまで戻ること」を意味する。アップロードしたテンプレートの不備などが原因でリソースの構築に失敗した場合、アップロードする前の状態に戻すロールバック機能がCloudFormationに備わっている |
テンプレートの基本的な書き方
ハンズオンで使用するCloudFormationテンプレートを元にテンプレートの基本的な書き方について説明します。
下記テンプレートはS3バケットを作成するものです。
AWSTemplateFormatVersion: "2010-09-09" # ①
Description: # ②
test-create-s3-bucket
Metadata: # ③
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: Required parameters
Parameters:
- environment
- bucketName1
-
Label:
default: If you set the environment parameter to pro, the following parameters are required
Parameters:
- bucketName2
Mappings: # ④
RegionMap:
ap-northeast-1:
name: tokyo
ap-northeast-3:
name: osaka
Parameters: # ⑤
bucketName1:
Type: String
Default: 'hoge'
bucketName2:
Type: String
Default: 'huga'
environment:
Type: String
Default: dev
AllowedValues:
- dev
- pro
Rules: # ⑥
devInstanceType:
RuleCondition: !Equals
- !Ref environment
- pro
Assertions:
- Assert: !Not [!Equals [!Ref bucketName2, huga]]
AssertDescription: 'If you set the environment parameter to pro, the bucketName2 parameters cannot set huga'
Conditions: # ⑦
isPro: !Equals [!Ref environment, pro]
Resources: # ⑧
S3Bucket1: # ⑧A
Type: 'AWS::S3::Bucket' # ⑧B
Properties: # ⑧C
BucketName: !Sub
- '${environment}-${region_name}-${bucketName1}'
- region_name: !FindInMap [RegionMap, !Ref "AWS::Region", name] # ④'
S3Bucket2:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Sub
- '${environment}-${region_name}-${bucketName2}'
- region_name: !FindInMap [RegionMap, !Ref "AWS::Region", name] # ④'
Condition: isPro # ⑦'
Outputs: # ⑨
BuketName1:
Value: !Ref S3Bucket1
BuketName2:
Value: !Ref S3Bucket2
Condition: isPro
①AWSTemplateFormatVersion
テンプレートファイルのバージョンを指定します。任意項目です。
2010-09-09
が最新のバージョンですが、それ以外のバージョンは発行されていないようです。
慣習としてファイルの一番上に記述します。
②Description
スタックの説明を記述します。任意項目です。
CloudFormationのスタック一覧の説明
として表示されます。
③Metadata
Parameters
で定義したパラメーターの表示順など、追加の設定ができます。任意項目です。
現在は以下3つの値を指定できます。
-
AWS::CloudFormation::Interface
- Parameterで指定した項目の順序やグループ分けを指定
-
AWS::CloudFormation::Init
- CloudFormationでEC2インスタンスを起動する際に役立つcfn-initヘルパースクリプトを使用する際に定義
-
AWS::CloudFormation::Designer
- CloudFormationのデザイナー機能を使用した場合、自動的に追加
上記テンプレートではAWS::CloudFormation::Interface
を使用し、グループをRequired parameters
、If you set ...
の2つに分けています。
また、前者はパラメーターをenvironment
、bucketName1
の順で表示するよう指定しています。
④Mappings
キーと値のセットを定義できます。任意項目です。
値は④'
で示している通り、Fn::FindInMap(省略型は!FindInMap)
で取得します。
この組み込み関数の引数の意味は!FindInMap ["マップ名", "上位階層キー名", "次階層キー名"]
です。
なお、テンプレートの上位階層キー名に指定しているAWS::Region
は擬似パラメータと呼ばれ、CloudFormationで事前定義されたパラメーターです。
AWS::Region
にはスタックを作成しているリージョン名(ap-northeast-1など)が設定されています。
今回は東京リージョンでスタックを作成した場合、tokyo
、大阪リージョンの場合、osaka
という文字列を取得するよう定義しています。
⑤Parameters
指定した値をAWS管理コンソールからスタックを作成する際、画面から入力させることができます。(もちろん、AWS CLIでスタック作成時に指定することもできます)任意項目です。
テキスト入力もできますし(bucketName1
、bucketName2
)、プルダウン(environment
)から選択させることもできます。
⑥Rules
パラメーターで入力した値やそれらの組み合わせの検証方法を定義できます。任意項目です。
上記テンプレートでは次の検証をしています。
- パラメーター
environment
の値がpro
の場合、以下のチェックを行う - パラメーター
bucketName2
の値がデフォルト値huga
以外の場合、問題ないとする
⑦Conditions
条件関数を定義できます。任意項目です。
条件関数を使用し、特定のリソースを生成するか・値を出力するかどうかを指定できます。
上記テンプレートではパラメーターenvironment
の値がpro
かどうか判定しています。
⑦'
でS3Bucket2
に対してこの条件を付与することでパラメーターenvironment
の値がpro
の場合、当該リソースを作成するようにしています。
⑧Resources
リソースを定義します。必須項目です。
⑧A
はリソースの論理名を指定します。テンプレート内で使用する任意の名称です。
⑧B
はリソースのタイプを指定します。作成したいリソースを識別する値を指定します。
どのような値が指定可能かは公式ドキュメントを参照してください。
⑧C
はリソースの設定値を指定します。
リソースのタイプごとに指定する値が異なります。適宜公式ドキュメントを参照する必要があります。
上記テンプレートでは、論理名はS3Bucket1
を指定しています。
リソースタイプはAWS::S3::Bucket
を指定し、S3バケットの生成を指定しています。
リソースの設定値はProperties
のBucketName
でバケットの名前を指定しています。
なお、!Sub
は値の代入を行うCloudFormationの組み込み関数であり、入力文字列の変数を指定した値に置き換えます。
テンプレートの${environment}-${region_name}-${bucketName1}
のように、${}
で変数を指定すればスタック作成時、自動的に変数の値に置き換えられます。
⑨Outputs
スタック作成後にコンソールに出力したい値(S3バケット名、APIのエンドポイントなど)や他スタックで参照させたい値(クロススタック参照)を定義する。任意項目です。
⑩Transform
AWS SAMを使用する場合に指定します。任意項目です。
または、CloudFormationがテンプレート内の処理を行う際に使用するマクロを定義します。
上記テンプレートにはこの項目は含まれていません。
ハンズオン
CloudFormationテンプレートの開発環境の準備
テンプレートはYAMLやJSON形式のファイルであるため、最悪メモ帳などがあれば作成できます。
しかし、Javaなどのプログラミングでも言えることですが、どこが間違っているかを指摘してくれたり(Linter)、入力補完機能などがあればもっと効率的にテンプレートの開発できます。
今回はVisual Studio Code(以降、VS Codeと呼ぶ)というMicrosoftが開発しているコードエディターでテンプレートを開発します。
また、VS Codeはさまざまな拡張機能を提供しています。これを使って、Linterや入力補完機能を追加し、開発を効率化します。
VS Codeのインストール
こちらのサイトの以下の章を実行してください。
Linter(CloudFormation Linter)のインストール
VS Code左メニューの4つの四角で構成されているアイコンをクリックすると、サイドメニューに拡張機能をインストールする画面が表示されます。
検索窓にCloudFormation Linter
と入力すると、一番上にCloudFormation Linter
という拡張機能が表示されることを確認します。
CloudFormation Linter
をクリックすると、メイン画面にその拡張の説明などが表示されます。
インストール
ボタンをクリックすると当該拡張機能のインストールが開始されます。
以下のような画面になればインストール完了です。
入力補完(CloudFormation support for Visual Studio Code)のインストール
CloudFormationの入力補完をするCloudFormation support for Visual Studio Code
についても同様の手順でインストールを行います。
テンプレートをアップロードし、S3バケットを構築する
実施前にテンプレートの基本的な書き方で提示したCloudFormationのコードをyamlファイルとして保存してください。
画面上部の検索窓にcloudformation
と入力し、表示されたCloudFormation
をクリックしてください。
左メニュスタック
が選択されていることを確認し、右上スタックの作成
、新しいリソースを使用(標準)
をクリックしてください。
スタックの作成方法などを入力します。
前提条件 - テンプレートの準備
セクションの入力です。
ここでは3つのスタックの作成方法を指定できます。
今回はテンプレートの準備完了
を選択してください。
テンプレートの指定
セクションの入力です。
テンプレートソース
ではCloudFormationにテンプレートをどこからアップロードするか指定できます。
今回はローカルからファイルをアップロードするため、テンプレートファイルのアップロード
を指定します。
テンプレートファイルのアップロード
のファイルの選択
ボタンをクリックし、本項の最初で作成したyamlファイルを選択してください。
最後に画面最下部右下の次へ
ボタンをクリックしてください。
次に、スタック名など入力します。
スタック名
セクションの入力です。
スタック名
は任意の文字列を入力してください。
パラメータ
セクションの入力です。
ここの入力欄はテンプレートのParameters
にパラメーターを指定していた場合、表示されます。
今回environment
、bucketName1
、bucketName2
を指定しているため、入力する必要があります。
environment
はデフォルトのdev
とします。
bucketName1
は任意の文字列で構いませんが、バケット名は全世界で一意でなければならないため、末尾に年月日を入れるなど工夫してください。
bukcetName2
はデフォルトのhuga
にしてください。
入力したら画面右下次へ
ボタンをクリックしてください。
今回environment
はdev
にしているため、bukcetName2
がhuga
でもエラーにならないことを確認してください。(⑥Rules参照)
次に、オプション設定を行います。
今回はとくに入力、変更が必要な項目はないため、画面最下部の次へ
ボタンをクリックして構いません。
1点アクセス許可
セクションについて説明します。
CloudFormationでのAWSリソース構築は、CloudFormationがユーザの代わりに実施してくれます。
そのため、CloudFormationにリソースを生成、削除、更新などの権限を与える必要があります。
権限付与はアクセス許可
セクションでIAMロールを指定する形で行うことができます。
また、IAMロールを指定しない場合、現在ログインしているIAMユーザの権限がCloudFormationに渡されます。
最後は確認画面です。
今までの入力内容を確認後、画面最下部の送信
ボタンをクリックしてください。
スタックの詳細画面に遷移します。
ここでスタックの作成状況などを確認できます。
左側スタック
セクションのステータス
がCREATE_IN_PROGRESS
になっているため、このスタックは現在作成中です。
右側のイベント
タブを選択するとリソース毎の作成イベントを確認できます。
左側スタック
セクションのステータス
がCREATE_COMPLETE
になったら、無事スタックを作成完了です。
リソース
タブを選択すると、スタックに含まれるリソースの一覧が閲覧できます。
リンクをクリックするとそのリソースの詳細画面に移動できるので便利です。
ここでテンプレートの内容と生成されたリソースを確認します。
今回パラメーターenvironment
でdev
を選択したため、テンプレート⑦'
のCondition
はfalse判定になりました。それによりS3Bucket2が生成されていない
ことを確認してください。
また、⑧C
でバケット名を${environment}-${region_name}-${bucketName1}
と指定しています。
environment
はdev
、region_name
は今回東京リージョンで生成しているため、tokyo
、bucketName1
はパラメーター入力値、以上の値が組み合わされたバケット名になっていることを確認してください。
出力
タブを選択すると、テンプレートのOutputs
に指定した情報の一覧が閲覧できます。
今回はバケット名を出力しています。こちらもCondition
の判定により、S3Bucket2のバケット名が出力されていない
ことを確認してください。
この出力値を別のテンプレートで参照することでテンプレートの分割をすることも可能です。(クロススタック参照)
作成したリソースを確認してみましょう。
リソース
タブの物理ID
がリンクになっているのでクリックしてください。
作成されたS3バケットの画面が表示されます。
Rulesの確認
前手順と同様にテンプレートをアップロードし、パラメーターを入力する画面に遷移します。
environment
でpro
を選択し、bucketName2
をデフォルト値huga
のまま、次へ
ボタンをクリックしてください。
エラーとなり、次の画面に遷移しないことを確認します。
Rules
によってパラメーターの入力バリデーションができることを確認することができました。
MappingとConditionsの確認
画面右上の東京
と記載されている箇所をクリックし、アジアパシフィック(大阪)
をクリックしてください。
これまでと同様にテンプレートをアップロードします。
パラメーターはenvironment
がpro
、bucketName1
、bucketName2
は一意な文字列を入力してください。
それ以降はこれまでと同様に手順を進めて、スタックの作成まで行ってください。
スタックが作成されたらリソース
タブを選択し、生成されたリソースを確認します。
S3Bucket1
のほかS3Bucket2
も生成されていることを確認してください。これは⑦'
のCondition
の結果がtrue判定になったからです。
また、バケット名を確認するとenvironment
の部分がpro
、region_name
がosaka
になっていることを確認してください。
スタックの削除
画面上部にある削除
ボタンをクリックしてください。
確認ダイアログが出ます。削除
ボタンをクリックしてください。
スタック
セクションのステータス
がDELETE_IN_PROGRESS
になり、スタックが削除中になります。
しばらくするとスタック
セクションから当該スタックが表示されなくなります。以上でスタックの削除が完了です。
S3画面から参照できていたS3バケットが参照できなくなっていることも併せて確認してみてください。
参考
- https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-anatomy.html#w2ab2c17c15b9
- https://dev.classmethod.jp/articles/cloudformation-beginner01/
- https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/quickref-s3.html
- https://dev.classmethod.jp/articles/lim-cfn-session-2-js-n/
- https://zenn.dev/ano/articles/c5eedcc31b30e2