62
41

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 5 years have passed since last update.

AWS CloudFormationでEC2を構築

Posted at

はじめに

最近AWSを始めたので、勉強がてらCloudFormationを用いてEC2の構築を行いました。

CloudFormationについて

CloudFormationはAWS内のインフラリソースを自動でプロビジョニングできるサービスです。
プロビジョニングしたいAWSリソースをコード(テンプレート)として記述し、目的のインフラ(スタック)を構築するというのがCloudFormationの流れになります。
(プロビジョニング : ネットワークやコンピューターリソースを準備すること)
参考:https://aws.amazon.com/jp/cloudformation/features/

インフラ構成図

インフラ構成は非常に単純で下図にようになります。
VPCは東京リージョンに作成し、パブリックサブネットはap-northeast-1aに作成しています。
EC2へのアクセスは指定した固定IPからのSSH, HTTPアクセスのみ許可しています。
EC2から外部へのアクセスは全て許可しています。

テンプレート記述の基本構文

テンプレートはJSONまたはYAML形式で記述することができ、今回はYAML形式で記述しています。
テンプレートの基本構文は以下のようになります。

# テンプレート形式のバージョン
AWSTemplateFormatVersion:

# テンプレートに関する記述
Description:

# 入力パラメータ
Parameters: 

# 構築するリソースの記述
Resources:

# 出力パラメータ
Outputs:

AWSTemplateFormatVersion

CloudFormationのテンプレート形式のバージョンで、2010-09-09が現時点での最新バージョンです。
2010-09-09が最新

Description

テンプレートの内容に関する記述です。

Parameters

記述したリソースに対し、パラメータを入力値として与えたい場合に記述します。
ここに記述したパラメータはテンプレートからスタックを作成する際に入力値として与えることになります。

Resources

構築したいAWSのリソースを記述します。

Outputs

ここに記述したパラメータはスタックの作成が終わったときに出力値として得られます。

リソース記述の基本構文

# リソースの論理名
(ResourceName):

  # リソースタイプ
  Type:

  # リソースのプロパティ
  Properties:

リソースの論理名

テンプレート内でのリソース名を記述します。

Type

リソースのタイプを指定します。
リソースタイプの参考:
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html

Properties

リソースのプロパティを指定します。

テンプレート解説

AWSTemplateFormatVersion: "2010-09-09"
Description: Provision EC2

テンプレートファイルの始めに形式のバージョンとテンプレート内容を記述しています。

Parameters: 
  KeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance
    Type: "AWS::EC2::KeyPair::KeyName"
  
  MyIP:
    Description: IP address allowed to access EC2
    Type: String

次に、EC2へのアクセスのキーペア名とアクセス可能なIPアドレスを入力パラメータとして設定しています。このように記述することで、テンプレートファイル内にキーペア名、IPアドレスを直接書く必要がなくなります。

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: vpc-cf

  IGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: igw-cf

  # IGWをVPCにアタッチ
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref IGW

ここからResourcesの記述になります。
まず記述内容は順にVPCの作成、インターネットゲートウェイ(IGW)の作成、IGWをVPCにアタッチとなります。
リソースのTags属性でNameタグを作成しています。
またAttachGatewayのプロパティVpcId, InternetGatewayIdにはそれぞれVPC, IGWのIDを指定する必要があるのですが、テンプレートの組み込み関数Refを用いることでリソースの論理名からIDを取得しています。
!Refは組み込み関数Refの短縮表記です。
組み込み関数Refについて:
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html

  PubSub:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-1a
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      Tags:
        - Key: Name
          Value: pub-sub-a-cf

  PubSubRT:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: pub-sub-a-rt-cf

  # PubSub-インターネット間のルーティング
  PubSubToInternet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PubSubRT
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref IGW
  
  # ルートテーブルをサブネットに関連付け
  AssoPubSubRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PubSub
      RouteTableId: !Ref PubSubRT

次はパブリックサブネットの作成です。
1番目のリソースで先ほど作成したVPC内にサブネットを作成しています。
2番目以降のリソースではそれぞれ、ルーティングテーブルの作成、パブリックサブネット-インターネット間のルートの作成、ルートテーブルのパブリックサブネットへの関連付けを行っています。

  EC2: 
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: ami-00d101850e971728d
      KeyName: !Ref KeyName
      InstanceType: t2.micro
      NetworkInterfaces: 
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref PubSub
          GroupSet:
            - !Ref EC2SG
      UserData: !Base64 |
        #!/bin/bash
        sudo yum install -y git
      Tags:
          - Key: Name
            Value: ec2-a-cf

次にEC2インスタンスの作成です。
EC2のAMIにはAmazon linux2を選択しています。今回は東京リージョンを選択していますが、リージョンが変わるとAMIのIDも変わるので、適宜変更する必要があります。テンプレート構文のMappingを使うことでリージョンについて条件判定を行った上で適切なAMIのIDを記述できるようです。
Mappingの利用:
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/gettingstarted.templatebasics.html
(ページ中程)

EC2にはパブリックIPを自動で割り振ります。
その場合ネットワークインターフェースはデバイスインデックスが0である必要があるのでNetworkInterfaces下の設定を行っています。
EC2のパブリックIP自動割り振りについて:
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html

UserDataに記述した内容はインスタンスの作成時に実行されるので、プログラムのインストールなど初期設定を行うことができます。
何もしないのは寂しいのでgitをインストールしています。
UserData属性にはBase64エンコードされたテキストを渡す必要があるので、組み込み関数!Base64を使用しています。
(!Base64は入力文字列のBase64表現を返します。)

  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: ec2-sg-cf
      GroupDescription: Allow SSH and HTTP access only MyIP
      VpcId: !Ref VPC
      SecurityGroupIngress:
        # http
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref MyIP
        # ssh
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref MyIP

次にEC2インスタンスのセキュリティーブループを記述しています。
自分のIPアドレスからのみHTTP, SSH接続を許可しています。

Outputs:
  EC2PublicIP:
    Value: !GetAtt EC2.PublicIp
    Description: Public IP of EC2 instance

最後に出力パラメータを記述しています。

スタックの作成

AWSにログインし、サービスメニューからCloudFormationのページに移ります。
次にCloudFormationページ内の"スタックの作成"ボタンをクリックすると次のような画面に移ります。
スクリーンショット 2019-05-26 19.00.46ーテンプ選択.png
テンプレートの選択項目のテンプレートをAmazon S3にアップロードを選択し、テンプレートファイルを選択して次へをクリックします。

スクリーンショット 2019-05-26 19.00.46ーテ<img width=
詳細指定の画面に移ります。テンプレートファイルのParametersに記述したパラメータをここで指定することができます。
次のページはタグやアクセス権限のページです。必要ならば入力して次の確認ページに進み、問題がなければ作成ボタンをクリックします。

スクリーンショット 2019-05-26 19.11.03ー作成済み.png スタックの作成画面に移ります。作成に多少時間がかかりますが、正常に完了すると状態の項目にCREATE_COMPLETEと表示されます。 また、下の出力タブ内にテンプレートのOutputsに記述したEC2のパブリックIPが表示されていることがわかります。 指定したIPでSSHで接続を行うことで設定どおりスタックが作成されていることが確認できます。

終わりに

  • テンプレートファイルのParametersやOutputsで入力パラメータや出力パラメータを設定できるのは非常に便利でした。いろいろと有効活用ができそう。
  • サブネットのルーティングの設定の部分はややコードが煩雑になってしまったので、もっと良い記述方法を探していきたいと思います。
  • 構築したスタック内のリソースを一括で削除できるのはすごく楽です。

参考

AWS CloudFormation公式ドキュメント
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html

62
41
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
62
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?