【AWS】CloudFormationでEC2を立ち上げてApache & php installまで

さぁて、今日も引き続きAWS CloudFormationの学習を継続しますよー

前回はCloudFormationでEC2立ち上げでSSHするとこまでやりましたhttps://www.royozaki.net/archives/888

今日はEC2にミドルウェア(Apacheとphp)もインストールしちゃいます

まず、完成したテンプレート(yaml)を載せておきます

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  KeyName:
    Description: input EC2 Keyname
    Type: 'AWS::EC2::KeyPair::KeyName'
Resources:
  testVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.0.0.0/16
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: testVPC
  testIGW:
    Type: 'AWS::EC2::InternetGateway'
    Properties:
      Tags:
        - Key: Name
          Value: testIGW
  PublicRoute:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref testVPC
      Tags:
        - Key: Name
          Value: PublicRoute
  Route:
    Type: 'AWS::EC2::Route'
    Properties:
      RouteTableId: !Ref PublicRoute
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref testIGW
  AttachIGW:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      InternetGatewayId: !Ref testIGW
      VpcId: !Ref testVPC
  testSubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      AvailabilityZone: ap-northeast-1a
      CidrBlock: 10.0.0.0/24
      VpcId: !Ref testVPC
      Tags:
        - Key: Name
          Value: testSubnet
  testSubnetRouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref testSubnet
      RouteTableId: !Ref PublicRoute
  testSG:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref testVPC
      GroupDescription: testIGW
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: testSG
  testEC2:
    Type: 'AWS::EC2::Instance'
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
              php: []
          files:
            /var/www/html/phpinfo.php:
              content: |
                <?php
                phpinfo();
                ?>
              mode: '000644'
              owner: apache
              group: apache
          services:
            sysvinit:
              httpd:
                enabled: 'true'
                ensureRunning: 'true'
    Properties:
      AvailabilityZone: ap-northeast-1a
      ImageId: ami-0318ecd6d05daa212
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      SubnetId: !Ref testSubnet
      SecurityGroupIds:
        - !Ref testSG
      Tags:
        - Key: Name
          Value: testEC2
      UserData: !Base64
        Fn::Sub: |
          #!/bin/bash -xe
          yum install -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource testEC2 --region ${AWS::Region}
  testEIP:
    Type: 'AWS::EC2::EIP'
    Properties:
      InstanceId: !Ref testEC2

こんな感じです。

前回からの変更点は、ResourcesセクションのtestEC2へApacheとphpをインストールする記述の追加のみです。
ちょっとtestEC2部分を抜粋すると、↓です。

  testEC2:
    Type: 'AWS::EC2::Instance'
    Metadata:              # <- 追加
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
              php: []
          files:
            /var/www/html/phpinfo.php:
              content: |
                <?php
                phpinfo();
                ?>
              mode: '000644'
              owner: apache
              group: apache
          services:
            sysvinit:
              httpd:
                enabled: 'true'
                ensureRunning: 'true'
    Properties:
      AvailabilityZone: ap-northeast-1a
      ImageId: ami-0318ecd6d05daa212
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      SubnetId: !Ref testSubnet
      SecurityGroupIds:
        - !Ref testSG
      Tags:
        - Key: Name
          Value: testEC2
      UserData: !Base64            # <- 追加
        Fn::Sub: |
          #!/bin/bash -xe
          yum install -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource testEC2 --region ${AWS::Region}

Metadataと、PropertiesにUserDataってのを追加しています。

MetadataにはAWS::CloudForamtion::Initタイプで予め定義されている形式に従って、インストールしたいミドルウェアを指定しています。
ここではpackagesにyumでhttpdとphpをインストールするようにしています。
また、filesではphpinfo.phpファイルを作成しています。
そして、servicesでhttpdサービスを起動しています。

UserDataに実行したいコマンドを記載しておくと、
EC2を立ち上げるときに、記載したコマンドを実行してくれます。

今回の例では、yum install -y aws-cfn-bootstrapでcfn-initヘルパースクリプト をインストールして、次の行でcfn-initヘルパースクリプトを実行しています。

cfn-initヘルパースクリプトってのは、上の方で書いたMetadataの内容を実行してくれるようです。https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-init.html

説明はここまでにして、
いつも通りスタック作っていきますか!

前回と同様に、SSHキー作って

$ aws ec2 create-key-pair --key-name TestCFPair --query 'KeyMaterial' --output text > TestCF.pem

create-stackします

$ aws cloudformation create-stack --stack-name teststack --template-body file://<ymlファイルのパス> --parameters ParameterKey=KeyName,ParameterValue=TestCFPair

しばらく待って、describe-instancesでPublicIpアドレスを調べて、
ブラウザでhttp://[PublicIpアドレス]/php.infoにアクセスしてみましょう!

よし!

ほな、用事も済んだし、さっさとスタック消しましょー

$ aws cloudformation delete-stack --stack-name teststack

本日もお疲れ様でした。


= 苦労話 =
最初、ミドルウェアがうまくインストールされなかったときにロールバックされるように、CreationPolicyとcfn-signalもテンプレートに記述していましたが、何度もロールバックされてしまう(30回くらいやったよ)ので、一旦ロールバックさせずにEC2内のログをみてやろうとCreationPolicyの記述消してみたところ、無事にミドルウェアまでインストールできていることが確認できました。

Please share this page:

コメントを残す