システムデザイン

AWS CloudFormationによるクラウドインフラの構築

*本記事は旧TechblogからCOLORSに統合した記事です。

こんにちは。エンジニアソリューション事業部のLです。
今回の記事ではAWS CloudFormationを用いて簡単なインフラ環境を構築してみようと思います。

目次

1.AWS CloudFormationとは?
2.コードの構成
3.コード作成の注意点
4.Refを活用しましょう

1.AWS CloudFormationとは


CloudFormationは、AWSリソースを自動で生成してくれるサービスです。
使いたいリソースをテンプレートファイルとして作成すれば、
CloudFormationが分析し、AWSリソースの生成を行うことができます。

出典:https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-whatis-howdoesitwork.html


特徴として以下が上げられます。

①インフラをコードで管理する(IaC)。
 テンプレートはYAMLもしくはJSONで作成できます。
 JSONで作業する際はコメントが削除されるため、YAMLをお勧めします。
 Gitなどとの連携で管理も便利です。個人的にはvscodeで作成しています。

②CloudFormationデザイナーを利用して作成することも可能です。

③料金は発生しません。
 CloudFormationを用いて作られたリソースで料金が発生します。

④同じ環境のコピーがしやすい。
 同じリージョンで同じ構成のテンプレートを使いたいときはスタックの名前を変えます。


実際使ってみた感想ですが、大枠を作るのは凄く簡単でした。
未経験からの中途1年目の僕でも簡単なVPC構成にDBサーバを構築することができましたので、
皆さんはもっと早く取得できると思います!
複数のテンプレートファイルでの構成も可能ですが、慣れるまでには時間がかかると思います。

2.コード構成


コード全体の構成は以下の順番になります。
①AWSTemplateFormatVersion
 - テンプレートのバージョン

AWSTemplateFormatVersion: "2010-09-09"


②Description(option)
 - テンプレートの説明。

Description: 
  Demo VPC and Subnet Create


③Parameters(option)
 - スタック生成時に使うパラメータ値
 - テンプレート内部でRef関数で参照
 - Outputsと組み合わせてテンプレート間を繋げることも可能

Parameters:
  VPCCIDR:
    Type: String
    Default: "10.0.0.0/16"


④Mappings(option)
 - ハッシュテーブルのようにkey-value構成
 - リージョン毎に使用するAMIを分ける時などに使う


⑤Resources
 - 使用するリソースを定義

Resources: 
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#
# Create VPC
  VPC: 
    Type: "AWS::EC2::VPC"
    Properties: 
      CidrBlock: !Ref VPCCIDR
      EnableDnsSupport: "true"
      EnableDnsHostnames: "true"
      InstanceTenancy: default
      Tags: 
        - Key: Name
          Value: !Sub "${Demo}"


⑥Outputs(option)
 - テンプレートで生成されたリソースの結果を出力する

Outputs:
# VPC
  VPC:
    Value: !Ref VPC
    Export:
      Name: !Sub "${Demo}-VPC"


3.コード作成の注意点


コード作成について注意するべきものがあります。
リファレンスの値を書く時、「大文字・小文字をしっかり守る事」です。
例えば、以下のコードをご覧ください。

# ------------------------------------------------------------#
# Security Group
# ------------------------------------------------------------# 
# Security Group for RDS. Allow 3306 from Lab3 vpc
  DBInstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow 3306 from PubSub
      VpcId: !Ref VPC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 3306
        ToPort : 3306
        CidrIp: "10.0.0.0/16" #lab3 vpc cidr
      SecurityGroupEgress:
      - IpProtocol: tcp
        FromPort: 3306
        ToPort: 3306
        CidrIp: "10.0.0.0/16" #lab3 vpc cidr


上記はRDSに設定させるためのSecurity Groupを定義したコードです。

例えば:
GroupDescription、VpcId、IpProtocolなどについて大文字と小文字を間違えるとエラーが起きてします。
最初は正しく書いたつもりなのになぜ動かないんだ!と思い込んでしまい、苦労しました。。。
皆さんはこのようなことがないように。


また、CloudFormationを実行するための権限も用意する必要があります。
自分が使うサービスをチェックし、どんな権限が必要か確認して的確なロールを割り当てることがベストプラクティスへの道になると思います。


4.Refを活用しましょう


レファレンスを利用することで、よりスマートに環境が作れます!
Refはパラメータからの参照だけでなく、リソース同士も使えます。
例として簡単なEC2作成のコードを紹介いたします。

  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      SubnetId: !Ref PublicSubnet1
       Volumes:
         - Device: "/dev/sda1"
           VolumeId: !Ref EC2Volume
      InstanceType: t2.micro
      ImageId: ami-0873b46c45c11058d   # Amazon Linux2 AMI - Oregon
      KeyName: "test"
      UserData:
        'Fn::Base64': 
          !Sub |
            #!/bin/bash
            yum -y update

            # install apache
            yum install httpd24 -y  

            # start server
            systemctl enable httpd
            systemctl start httpd
      SecurityGroupIds:
        - !Ref EC2SecurityGroup
      Tags:
        - Key: Name
          Value: WebServer test
      Monitoring: false


Ref関数で「PublicSubnet1」、「EC2SecurityGroup」を読み取っています。
これらは以下のように定義しています。

# Create Public Subnet 1
  PublicSubnet1: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      MapPublicIpOnLaunch: True
      AvailabilityZone: !Ref AZ1
      CidrBlock: !Ref PublicSubnet1CIDR
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${Demo}-PubSub1"

...

# Security Group for Webserver-EC2. Allow HTTP from all
  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow HTTP from All
      VpcId: !Ref VPC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort : 80
        CidrIp: "0.0.0.0/0"



いかがでしたか?
簡単な個人サーバの構築から、テスト環境構築、少しの修正で本番環境、
それを量産など自動化の使い道は色々あると思います!
ぜひ活用していきましょう!
読んでいただきありがとうございました!