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?

インフラ構築を簡単にするAWS CloudFormation

Last updated at Posted at 2024-10-28

皆さん、こんにちは! おすすめの牛は短角牛、ITエンジニアのSkyfox(なかやま)です!
この記事を読んで、AWS CloudFormationを使ってくださると嬉しいです!

この記事について

対象者

  • 手作業でAWS環境構築するのに疲れた方
  • CloudFormationに興味がある方
  • AWSリソースをマネージドコンソールで作成したことがある方

本記事のゴール

  • CloudFormationの概要がわかること
  • CloudFormationを使用してみようかという気持ちになること

背景

AWS環境をマネージドコンソールで作成したことがある皆さん、こんなことを思ったことはありませんか?

image.png

今回の記事では、このようなお悩みを解決します。

CloudFormationの概要

AWS CloudFormationとは

AWS CloudFormationは、AWSのインフラ構成をコードで作成・管理してくれるサービスです。
いわば、あなたの作業チームの
インフラ構築・管理をしてくれる、 もう1人のメンバー
です!

メリット・デメリット

メリット

  • インフラ構成をコード化できる
    CloudFormationを使用すると、AWSリソースの設定をコードとして管理できます。
    これにより、リソースの構成が管理しやすくなり、誰でも同じ環境を構築することができるようになります。

  • 作業効率がUPする
    インフラ構成をコード化してしまえば、複数のAWSリソースを一度に自動で作成、更新、削除することができます。
    手動の設定作業が不要になるため、作業効率が大幅に上がります。

  • 環境・用途ごとに柔軟に対応できる
    AWSリソースを作成するとき、開発環境や本番環境などに合わせて、リソースの設定をすることができます。

  • 変更履歴を管理できる
    リソースの更新や変更履歴がCloudFormationで管理できるため、誰が何を変更したかがわかるようになっています。
    そのため、問題が起きたときに原因を特定しやすくなります。

デメリット

  • エラーメッセージがわかりにくい
    コード側でエラーが発生したとき、エラーメッセージがわかりにくく、原因を特定することが難しいことがあります。

  • コード化には慣れが必要
    コードを書くルールがあるため、CloudFormationを使い始めた方だと、はじめはコード作成に慣れが必要です。
    (最近は身近なAIもあるので、簡単な構成であれば、コードを書かずにできるやも)

  • 複雑なコードにすると読みづらい
    コード化するときに内容が複雑になると、読みづらく、保守が難しくなることがあります。

  • デプロイに時間がかかることがある
    多くのリソースを管理している場合、コードの変更やリソースの削除に時間がかかることがあります。

CloudFormationを使用するための前知識

前章までで、CloudFormationの概要や良さは、わかったかと思います。
それでは、実際にみなさんが使えるようになるため、ここからは必要な知識をインプットしていきましょう!

主なキーワード

  • テンプレート
    • リソースの設定や構成など、インフラ構成に必要な情報を定義するファイル
    • YAML形式 or JSON形式で書きます
    • ※前章まで「コード化」と言っていたのは、これのことです

  • スタック
    • テンプレートをもと作成されたAWSリソースのコレクション(集合体)
    • スタック単位でリソースの作成・更新・削除をおこない、一括管理ができます
    • ※テンプレートをもとに作成されたリソースたちを、まとめて管理する単位としても呼ばれています

  • 変更セット
    • スタックを更新する前に、その内容をプレビューする機能
    • どのリソースが追加・更新・削除されるかを一目で確認できます

リソース作成までの流れ

流れはたったの3ステップです。

  1. テンプレートの作成
  2. デプロイ(スタックの作成)
    ※AWS マネージドコンソール or CLI
  3. スタックをもとに設定されたAWSリソースが自動的に生成

image.png


それでは、詳しくみていきましょう!

テンプレートの書き方

覚えておきたい5セクション

テンプレートを作るときは、作りたいシステム構成を思い描いてから作りましょう!
今回はyaml形式で書いていきます。

テンプレートは、以下の7つのセクションで構成されています。
重要なのは、赤枠がついた5つです。

image.png

  • 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使用

image.png

PracticeStack.yaml
# [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」ファイルを作成してください!

<今回の構成>
image.png

ステップ1

CloudFormationのコンソールを開き、「スタックの作成」の「新しいリソースを使用(標準)」(画像の赤枠)をクリックします。

image.png

ステップ2

「スタックの作成」ステップでは、今回すでに作成してあるテンプレートを使いたいので、画像のように設定していきます。
テンプレートの設定は、「テンプレートの指定」項目の「ファイルの選択」ボタン(画像の赤枠)をクリックし、指定します。

image.png

ステップ3

「スタックの詳細を指定」ステップでは、以下の設定をします。

  • 設定
    • スタック名を提供
      • スタック名: ※適したスタック名をつけてください
    • パラメータ
      • ※ テンプレートの内容により変化します
        • テンプレートの「Parameters」セクションで設定した項目が表示されます
        • ここで今回作成したいスタックの設定値を選択していきます

注意
前章のテンプレートを使用している方は、LowCost環境とHighPerformance環境で、コストが異なるので注意です!

image.png

ステップ4

「スタックオプションの設定」ステップでは、適宜設定します。

image.png

ステップ5

「確認して作成」ステップで、設定した項目を確認し、大丈夫でしたら、「送信」ボタンをクリックします。

ステップ6

画像のように、CloudFormationと作成したリソースが以下のように確認できましたら、完成です。

  • CloudFormationのスタック確認
    • 作成したスタックの「ステータス」項目が「CREATE_COMPLETE」になっている
      image.png

  • 作成したリソース(今回はEC2など)の確認
    • 作成したかったリソースができているか確認します
      image.png

Appendix

変更セットについて

今回は詳細には書きませんが、スタック更新時に以下の赤枠のように、変更があるリソースを「変更セットのプレビュー」項目で表示してくれます。
これで変更した内容が合っているか確認してから、スタックを更新することができます。
(「間違って必要なリソースを消してしまった」ということも防げます。)

image.png

さいごに

AWS CloudFormationのイメージは、つきましたでしょうか?

この記事を導入としてもらい、
AWSリソースを一括作成・管理する
インフラ構築・管理をしてくれる、 もう1人のメンバー
として、AWS CloudFormationで快適なインフラ構築を実施してもらえればと思います。

使用イラスト

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?