0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CloudFormationでAWSサーバレスアーキテクチャを構築する その1

Last updated at Posted at 2023-11-01

はじめに

本記事は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のテーブルに格納

system.png

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のスタック一覧の説明として表示されます。

スクリーンショット 2023-09-07 22.37.44.png

③Metadata

Parametersで定義したパラメーターの表示順など、追加の設定ができます。任意項目です。
現在は以下3つの値を指定できます。

  • AWS::CloudFormation::Interface
    • Parameterで指定した項目の順序やグループ分けを指定
  • AWS::CloudFormation::Init
  • AWS::CloudFormation::Designer
    • CloudFormationのデザイナー機能を使用した場合、自動的に追加

上記テンプレートではAWS::CloudFormation::Interfaceを使用し、グループをRequired parametersIf you set ...の2つに分けています。
また、前者はパラメーターをenvironmentbucketName1の順で表示するよう指定しています。

スクリーンショット 2023-09-08 1.40.18.png

④Mappings

キーと値のセットを定義できます。任意項目です。
値は④'で示している通り、Fn::FindInMap(省略型は!FindInMap)で取得します。
この組み込み関数の引数の意味は!FindInMap ["マップ名", "上位階層キー名", "次階層キー名"]です。

なお、テンプレートの上位階層キー名に指定しているAWS::Region擬似パラメータと呼ばれ、CloudFormationで事前定義されたパラメーターです。
AWS::Regionにはスタックを作成しているリージョン名(ap-northeast-1など)が設定されています。

今回は東京リージョンでスタックを作成した場合、tokyo、大阪リージョンの場合、osakaという文字列を取得するよう定義しています。

⑤Parameters

指定した値をAWS管理コンソールからスタックを作成する際、画面から入力させることができます。(もちろん、AWS CLIでスタック作成時に指定することもできます)任意項目です。
テキスト入力もできますし(bucketName1bucketName2)、プルダウン(environment)から選択させることもできます。

スクリーンショット 2023-09-07 7.26.44.png

⑥Rules

パラメーターで入力した値やそれらの組み合わせの検証方法を定義できます。任意項目です。
上記テンプレートでは次の検証をしています。

  • パラメーターenvironmentの値がproの場合、以下のチェックを行う
  • パラメーターbucketName2の値がデフォルト値huga以外の場合、問題ないとする

⑦Conditions

条件関数を定義できます。任意項目です。
条件関数を使用し、特定のリソースを生成するか・値を出力するかどうかを指定できます。

上記テンプレートではパラメーターenvironmentの値がproかどうか判定しています。
⑦'S3Bucket2に対してこの条件を付与することでパラメーターenvironmentの値がproの場合、当該リソースを作成するようにしています。

⑧Resources

リソースを定義します。必須項目です。
⑧Aはリソースの論理名を指定します。テンプレート内で使用する任意の名称です。
⑧Bはリソースのタイプを指定します。作成したいリソースを識別する値を指定します。
どのような値が指定可能かは公式ドキュメントを参照してください。
⑧Cはリソースの設定値を指定します。
リソースのタイプごとに指定する値が異なります。適宜公式ドキュメントを参照する必要があります。

上記テンプレートでは、論理名はS3Bucket1を指定しています。
リソースタイプはAWS::S3::Bucketを指定し、S3バケットの生成を指定しています。
リソースの設定値はPropertiesBucketNameでバケットの名前を指定しています。

なお、!Subは値の代入を行うCloudFormationの組み込み関数であり、入力文字列の変数を指定した値に置き換えます。
テンプレートの${environment}-${region_name}-${bucketName1}のように、${}で変数を指定すればスタック作成時、自動的に変数の値に置き換えられます。

⑨Outputs

スタック作成後にコンソールに出力したい値(S3バケット名、APIのエンドポイントなど)や他スタックで参照させたい値(クロススタック参照)を定義する。任意項目です。

スクリーンショット 2023-09-07 8.10.33.png

⑩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という拡張機能が表示されることを確認します。

スクリーンショット 2023-09-05 20.31.37.png

CloudFormation Linterをクリックすると、メイン画面にその拡張の説明などが表示されます。

スクリーンショット 2023-09-05 20.32.04.png

インストールボタンをクリックすると当該拡張機能のインストールが開始されます。
以下のような画面になればインストール完了です。

スクリーンショット 2023-09-05 20.32.35.png

入力補完(CloudFormation support for Visual Studio Code)のインストール

CloudFormationの入力補完をするCloudFormation support for Visual Studio Codeについても同様の手順でインストールを行います。

スクリーンショット 2023-09-05 20.36.06.png
スクリーンショット 2023-09-05 20.36.25.png
スクリーンショット 2023-09-05 20.36.42.png

テンプレートをアップロードし、S3バケットを構築する

実施前にテンプレートの基本的な書き方で提示したCloudFormationのコードをyamlファイルとして保存してください。

画面上部の検索窓にcloudformationと入力し、表示されたCloudFormationをクリックしてください。

スクリーンショット 2023-09-07 6.33.16.png

左メニュスタックが選択されていることを確認し、右上スタックの作成新しいリソースを使用(標準)をクリックしてください。

スクリーンショット 2023-09-07 6.33.58.png

スタックの作成方法などを入力します。
前提条件 - テンプレートの準備セクションの入力です。
ここでは3つのスタックの作成方法を指定できます。
今回はテンプレートの準備完了を選択してください。

テンプレートの指定セクションの入力です。
テンプレートソースではCloudFormationにテンプレートをどこからアップロードするか指定できます。
今回はローカルからファイルをアップロードするため、テンプレートファイルのアップロードを指定します。
テンプレートファイルのアップロードファイルの選択ボタンをクリックし、本項の最初で作成したyamlファイルを選択してください。

最後に画面最下部右下の次へボタンをクリックしてください。

スクリーンショット 2023-09-07 6.36.44.png

次に、スタック名など入力します。
スタック名セクションの入力です。
スタック名は任意の文字列を入力してください。

パラメータセクションの入力です。
ここの入力欄はテンプレートのParametersにパラメーターを指定していた場合、表示されます。
今回environmentbucketName1bucketName2を指定しているため、入力する必要があります。
environmentはデフォルトのdevとします。
bucketName1は任意の文字列で構いませんが、バケット名は全世界で一意でなければならないため、末尾に年月日を入れるなど工夫してください。
bukcetName2はデフォルトのhugaにしてください。
入力したら画面右下次へボタンをクリックしてください。
今回environmentdevにしているため、bukcetName2hugaでもエラーにならないことを確認してください。(⑥Rules参照)

スクリーンショット 2023-09-08 2.33.41.png

次に、オプション設定を行います。
今回はとくに入力、変更が必要な項目はないため、画面最下部の次へボタンをクリックして構いません。

1点アクセス許可セクションについて説明します。
CloudFormationでのAWSリソース構築は、CloudFormationがユーザの代わりに実施してくれます。
そのため、CloudFormationにリソースを生成、削除、更新などの権限を与える必要があります。
権限付与はアクセス許可セクションでIAMロールを指定する形で行うことができます。
また、IAMロールを指定しない場合、現在ログインしているIAMユーザの権限がCloudFormationに渡されます。

スクリーンショット 2023-09-07 7.44.04.png

最後は確認画面です。
今までの入力内容を確認後、画面最下部の送信ボタンをクリックしてください。

スクリーンショット 2023-09-07 7.20.54.png

スタックの詳細画面に遷移します。
ここでスタックの作成状況などを確認できます。
左側スタックセクションのステータスCREATE_IN_PROGRESSになっているため、このスタックは現在作成中です。
右側のイベントタブを選択するとリソース毎の作成イベントを確認できます。

スクリーンショット 2023-09-07 7.22.36.png

左側スタックセクションのステータスCREATE_COMPLETEになったら、無事スタックを作成完了です。

スクリーンショット 2023-09-08 2.40.55.png

リソースタブを選択すると、スタックに含まれるリソースの一覧が閲覧できます。
リンクをクリックするとそのリソースの詳細画面に移動できるので便利です。
ここでテンプレートの内容と生成されたリソースを確認します。
今回パラメーターenvironmentdevを選択したため、テンプレート⑦'Conditionはfalse判定になりました。それによりS3Bucket2が生成されていないことを確認してください。
また、⑧Cでバケット名を${environment}-${region_name}-${bucketName1}と指定しています。
environmentdevregion_nameは今回東京リージョンで生成しているため、tokyobucketName1はパラメーター入力値、以上の値が組み合わされたバケット名になっていることを確認してください。

スクリーンショット 2023-09-08 2.41.31.png

出力タブを選択すると、テンプレートのOutputsに指定した情報の一覧が閲覧できます。
今回はバケット名を出力しています。こちらもConditionの判定により、S3Bucket2のバケット名が出力されていないことを確認してください。
この出力値を別のテンプレートで参照することでテンプレートの分割をすることも可能です。(クロススタック参照

スクリーンショット 2023-09-08 2.48.44.png

作成したリソースを確認してみましょう。
リソースタブの物理IDがリンクになっているのでクリックしてください。
作成されたS3バケットの画面が表示されます。

スクリーンショット 2023-09-08 2.49.33.png

Rulesの確認

前手順と同様にテンプレートをアップロードし、パラメーターを入力する画面に遷移します。
environmentproを選択し、bucketName2をデフォルト値hugaのまま、次へボタンをクリックしてください。
エラーとなり、次の画面に遷移しないことを確認します。
Rulesによってパラメーターの入力バリデーションができることを確認することができました。

スクリーンショット 2023-09-08 2.52.36.png

MappingとConditionsの確認

画面右上の東京と記載されている箇所をクリックし、アジアパシフィック(大阪)をクリックしてください。

スクリーンショット 2023-09-08 2.55.23.png

これまでと同様にテンプレートをアップロードします。
パラメーターはenvironmentprobucketName1bucketName2は一意な文字列を入力してください。
それ以降はこれまでと同様に手順を進めて、スタックの作成まで行ってください。

スクリーンショット 2023-09-08 2.57.11.png

スタックが作成されたらリソースタブを選択し、生成されたリソースを確認します。
S3Bucket1のほかS3Bucket2も生成されていることを確認してください。これは⑦'Conditionの結果がtrue判定になったからです。
また、バケット名を確認するとenvironmentの部分がproregion_nameosakaになっていることを確認してください。

スクリーンショット 2023-09-08 3.02.37.png

スタックの削除

画面上部にある削除ボタンをクリックしてください。

スクリーンショット 2023-09-07 8.18.40.png

確認ダイアログが出ます。削除ボタンをクリックしてください。

スクリーンショット 2023-09-07 8.19.12.png

スタックセクションのステータスDELETE_IN_PROGRESSになり、スタックが削除中になります。
しばらくするとスタックセクションから当該スタックが表示されなくなります。以上でスタックの削除が完了です。
S3画面から参照できていたS3バケットが参照できなくなっていることも併せて確認してみてください。

スクリーンショット 2023-09-07 8.19.44.png

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?