環境構築

AWSにおけるLAMP環境構築(CloudFormation編)

こんにちは。issaです。
まさかの3週連続登場となりました!
せっかくなので、引き続きAWSネタで攻めてみたいと思います。

前回までは、手動で設定していきましたので
どういったものを利用して設定しているかの理解を深められたかと思います。
今回はそれを自動で作成してしまおうという試みです。

最速で前回と同じEC2 1台RDS1台の環境を構築したい人は、事前にログイン時の共有キーを作成した後
こちらのコードをテンプレート保存して実行してください!
ものの10分ほどで環境ができあがってるはずです!利用する前に、セキュリティ設定の見直しだけはお忘れなく。
※サンプルコードでは共有キー名を「testSampleKey」としていますので合わせるかコードの設定を変更してご利用ください。
 キーペア作成の詳細はこちら。


それ以外の方は、一緒に順を追って構築していきましょう。

構成図

それでは、CloudFormationネタということでいきなりこちらのページへ来られた方のために、まずは構成図をご覧ください。

サーバー構成としては前回と同じ下記となります。

ネットワーク構成は下記設定でおこなっていきます。

VPC:192.168.0.0/16
サブネット1:192.168.10.0/24 (AvailabilityZone: ap-northeast-1a)
サブネット2:192.168.20.0/24 (AvailabilityZone: ap-northeast-1c)
WEBサーバーIP:192.168.10.10
WEBサーバーアクセス許可IP, ポート:192.168.0.1, 22ポート,80ポート

※「WEBサーバーアクセス許可IP」は仮にローカルIPを指定していますが、ご自分の環境のグローバルIPへと読み替えてください。
DBサーバーアクセス許可IP, ポート:192.168.10.10, 3306ポート

インスタンス設定自体は2か所でしたが、実際にはこの図のようにデフォルト設定で利用していたVPCやサブネット等のネットワーク設定が含まれていたのですね!

CloudFormation Designerツール

CloudFormationを利用するにあたり、今回は下記コードをテンプレートとして登録してみましょう。まずはツールを起動していきます。

①「サービス」をクリックし、全項目を表示。
②「管理ツール」より、「CloudFormation」をクリック。

①「テンプレートをデザイン」ボタンをクリック。

ツールが開きましたか?
一から作成する際には、画面左の「リソースタイプ」から各サービスを選択して設定していくことになります。
今回は、こちらのコードを下部のエディタへ張り付け、それを図に反映してみましょう。

①「テンプレート」タブをクリック。
②今回はYAML形式でサンプルを用意していますので「YAML」をクリックし。
③テキストエリアへコードを貼り付けます。

①貼り付けが終わりましたら、Designerツールがコードと図があっていない旨のメッセージが表示されています。
②「リフレッシュ」ボタンをクリックして、コードと同期させてください。

図のような感じで表示されましたでしょうか。
①見づらい場合は「ウィンドウに合わせる」ボタンがありますのでこちらをクリック。

①コンポーネントをクリックすると
②該当するコードがハイライトされます。
 設定の追加や変更はコードから探さなくとも、ここから可能です。

下記をおこなうことにより、コンポーネント毎の設定も閲覧・編集可能です。
①「コンポーネント」タブをクリック。
②「コンポーネント」のアイコンをクリック。

コード説明

それでは、部分的に見ていきましょう。

CloudFormationのDesignerツール用設定

2行目から171行目まではCloudFormationのDesignerツールで図示するための設定パラメーターとなります。ツールで「コンポーネント」のアイコンを移動したりすると、自動的に変更してくれます。
また、コード中の

    Metadata:
      'AWS::CloudFormation::Designer':
        id: xxxxxxxxxxxxxxxx

となっているか所に関しても同様です。
こちらで意識する必要はありません。

Resources以下が、各コンポーネントへの設定値になっていきます。
今回の場合、大きく分けると下記3パートに分けて記載しています。
サンプルコードへは、下記と同じ名称でコメントを入れています。

ネットワーク設定

それでは、コード内にコメントで説明していきます。
なお、Metadataは自動設定ですから削除しています。

  TestVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 192.168.0.0/16
  TestInternetGateway:
    Type: 'AWS::EC2::InternetGateway'
    Properties: {}
  TestVPCGatewayAttachment:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref TestVPC
      InternetGatewayId: !Ref TestInternetGateway
  TestSubnet1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref TestVPC
      AvailabilityZone: ap-northeast-1a
      CidrBlock: 192.168.10.0/24
  TestSubnet2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref TestVPC
      AvailabilityZone: ap-northeast-1c
      CidrBlock: 192.168.20.0/24
  TestDBSubnetGroup:
    Type: 'AWS::RDS::DBSubnetGroup'
    Properties:
      SubnetIds:
        - !Ref TestSubnet1
        - !Ref TestSubnet2
      DBSubnetGroupDescription: testDBSubnetGroup
  TestRouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref TestVPC
  TestRoute:
    Type: 'AWS::EC2::Route'
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      RouteTableId: !Ref TestRouteTable
      GatewayId: !Ref TestInternetGateway
  TestSubnetRouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      RouteTableId: !Ref TestRouteTable
      SubnetId: !Ref TestSubnet1

このパートでは、外部通信やEC2とRDS相互の通信に必要となる下記が設定されています。

  • VPC
  • InternetGateway
  • RouteTable
  • ap-northeast-1aゾーン用サブネット
  • ap-northeast-1cゾーン用サブネット
  • RDS用サブネットグループ

ここに、WEBサーバーやDBサーバーを接続することにより通信が可能になります。
設定可能なプロパティに関しては、下記URLを参照ください。
今回は必須項目とIP以外はデフォルト設定を踏襲しています。

WEBサーバー設定

基本的には、前回と同様の設定となります。
こちらは、個別に設定している項目も多いのでインラインのコメントで解説していきます。

# WEBサーバー設定
  ## セキュリティグループの設定をしていきます。
  TestSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref TestVPC
      GroupDescription: ownIpAddressGroup
      ## ここで、セキュリティ設定を行なっています。
      ## 192.168.0.1の箇所を許可したいIPに変更してください。
      ## Portは許可したいポートに対してのレンジ指定です。送信元と送信先ではありません。
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 192.168.0.1/32
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 192.168.0.1/32

  ## ここからがEC2インスタンスの設定になります。
  TestWebServer1:
    Type: 'AWS::EC2::Instance'
    Properties:
      ## 今回は無料で利用可能なt2.microインスタンスを指定しています。
      InstanceType: t2.micro
      ## アベイラビリティゾーンを東京のa側に指定しています。
      AvailabilityZone: ap-northeast-1a
      ## 前回と同じRedHatのAMI IDです。このIDは予めAMIを作成しておいたものを利用しても良いですし、AWS Marketplaceから選択してもかまいません。
      ImageId: ami-eb50cd8d
      ## コンソールログイン時に使用するキーの名称です。予め用意してダウンロードしておきましょう。
      KeyName: testSampleKey
      ## HDDの指定です。VolumeSizeの単位はGBです。
      BlockDeviceMappings:
        - DeviceName: /dev/sda1
          Ebs:
            VolumeSize: 15
      ## NIC情報を指定します。
      ## 今回は、動的パブリックIPを自動付与にして
      ## プライベートIDとして192.168.10.10を設定しています。
      ## 属するサブネットと同じ帯域で設定しましょう。
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          SubnetId: !Ref TestSubnet1
          DeleteOnTermination: true
          PrivateIpAddress: 192.168.10.10
          DeviceIndex: '0'
          GroupSet:
            - !Ref TestSecurityGroup
      ## OSインストール完了後の初期化処理です。
      ## 前回と同様のインストールを自動でやってしまいます!
      ## ここでは、各種インストールからphpinfoの表示ページの配置まで実施しています。
      UserData: !Base64 
        'Fn::Join':
          - ''
          - - |
              #!/bin/bash
            - |
              yum -y remove mariadb-libs
            - |
              yum -y update
            - >
              rpm -ivh
              http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
            - |
              yum -y install mysql httpd
            - >
              yum -y install
              http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm
            - >
              yum -y install
              http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
            - |
              yum -y install --enablerepo=remi-php72 php php-mysql
            - |
              systemctl enable httpd.service
            - |
              systemctl start httpd.service
            - |
              echo ' /var/www/html/info.php
            - |
              echo 'phpinfo();'  >> /var/www/html/info.php
            - |
              setsebool -P httpd_can_network_connect_db on

DBサーバー設定

続いてDBサーバーの設定も見ていきましょう。

  ## パラメータグループを作っておきます。
  ## ここではベースの指定のみですが、各パラメータの設定も可能です。
  TestDBParameterGroup:
    Type: 'AWS::RDS::DBParameterGroup'
    Properties:
      Description: mysql57CustomParameter
      Family: mysql5.7
  ## セキュリティグループの設定です。
  ## 先ほど作成したWEBサーバーのIPアドレスからのみ許可としています。
  TestRdsSecurityGroups:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: RdsSecurityGroup
      SecurityGroupIngress:
        - IpProtocol: tcp
          CidrIp: 192.168.10.10/32
          FromPort: '3306'
          ToPort: '3306'
      VpcId: !Ref TestVPC
  ## DBインスタンスの設定です。
  ## 設定項目は、前回と同様にしています。
  TestDbServer1:
    Type: 'AWS::RDS::DBInstance'
    Properties:
      DBParameterGroupName: !Ref TestDBParameterGroup
      MultiAZ: false
      DBInstanceClass: db.t2.micro
      AllocatedStorage: 20
      StorageType: gp2
      DBInstanceIdentifier: test-hogehoge
      MasterUsername: master_hogehoge
      MasterUserPassword: hogehogepw
      DBName: hogehoge_db
      Engine: mysql
      EngineVersion: 5.7.19
      Port: 3306
      AvailabilityZone: ap-northeast-1a
      VPCSecurityGroups:
        - !Ref TestRdsSecurityGroups
      DBSubnetGroupName: !Ref TestDBSubnetGroup


確認

ある程度コードの内容まで分かったところで、実際にリソースを作って確認していきましょう。

Designerツール操作

①画面左上の「リソースの作成」ボタンをクリック

①「次へ」ボタンをクリック

①適当なスタックの名前を入力してください。
②「次へ」ボタンをクリック。

ここで、誤操作等を考慮してアクセス権限を付与することも可能です。
今回は検証環境のため、特に設定せずに進みます。
①「次へ」ボタンをクリック。


①「作成」ボタンをクリック。

①図のような状態になりましたでしょうか。初期状態から更新されていない場合はこの「更新」ボタンをクリックしてください。
②先ほど作成した名前が確認できます。
③作成中の状況が確認できます。
 ここが「CREATE_COMPLETE」となれば完成です!
 通常は自動で更新されますが、変わらない場合は①の「更新」ボタンをクリックしてください。

完了しましたら、ブラウザーより「http://IPv4 パブリック IP/info.php」へアクセスしてみてください。
図のようにPHPの情報が表示されたら成功です!
※IPアドレスは、EC2のインスタンス一覧より確認してください。

既にPHPからMySQLへの接続も可能ですので、前回の記事を参考にファイルを配置すればそちらの確認ももちろん可能です!

まとめ

いかがでしたでしょうか。
どれが必要なのか。というのが、ネットワーク周りは分かりづらかったかもしれませんが、基本的にはGUIで設定・選択していたものと同じです。
あらかじめデフォルトで設定されていましたので、あらためて前回の設定を確認してみるのも良いかと思います。

全体のコード量としては、それなりの行数になっていましたがコンポーネント単位で見ていくとそれほどでもないことに驚かれるかもしれませんね。頻繁に作成する機会のある環境の方でしたら、ぜひこれを利用して楽しちゃいましょう!

※本番運用時には、もっとしっかりと設定を入れ込みましょう!

LINEで送る
Pocket

この記事を書いた人・プロフィール
issa
ニックネーム: issa

カタリスト創業メンバーの一人。
主にPHPを使う事が多いですが、過去にかじった言語は無数にあります。
社内NWの構築や各サーバの管理等インフラ周りも担当してます。

趣味:お酒、バイク、音楽(主にロックかボカロ)