CodeDeploy Getting Started: WordPressをDeployしてみよう

# CodeDeployで出来ること
CodeDeployを使うことで、アプリケーションソフトの開発・運用プロセスのうちDeploymentについて自動化をすることができます。

# CodeDeployを使うと嬉しいこと
下記Webページに書かれているような、AmazonのDeploymentシステム(Apollo)と同じようなDeploymentの自動化をAWS上で実現できます。
[The Story of Apollo - Amazon’s Deployment Engine](http://www.allthingsdistributed.com/2014/11/apollo-amazon-deployment-engine.html)
クラウドネイティブアプリを開発・運用する際には計算リソースが伸縮自在である必要がありますが、Deploymentの観点でも伸縮自在でないとクラウドの利点を活かせません。そのため、CodeDeployのようなツールの利用は今後広がっていくと考えられます。

# Getting Started: WordPressをDeployしてみよう
CodeDeployの使い方は、とても簡単です。下記のGetting Startedドキュメントに沿う形でEC2インスタンス上へのWordPressのDeploy手順についてまとめます。
[Getting Started with AWS CodeDeploy](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/getting-started.html)

## Setting Up AWS CodeDeploy
下記ドキュメントを参考に、CodeDeployを使用するためのIAMユーザを作成した上で必要なポリシーをアタッチします。
[Setting Up AWS CodeDeploy](http://docs.aws.amazon.com/codedeploy/latest/userguide/getting-started-setup.html)
また、CodeDeployの実行にはService Roleが必要になるため、下記ドキュメントに従い設定をします。
[Create a Service Role for AWS CodeDeploy](http://docs.aws.amazon.com/codedeploy/latest/userguide/how-to-create-service-role.html)

## Step 1: Launch an Amazon Linux or Red Hat Enterprise Linux Amazon EC2 Instance
はじめに、EC2インスタンスを起動します。CodeDeployを用いるためにはcodedeploy-agentをあらかじめインストールする必要があるため、ここではCloudFormationを用いてインスタンスの起動および設定をまとめて実施します。

```
$ wget http://bit.ly/1jRpVZk
  (http://s3-ap-northeast-1.amazonaws.com/aws-codedeploy-ap-northeast-1/templates/latest/CodeDeploy_SampleCF_Template.json は ap-northeast-1のAMIに対応していないため、一部修正したものを使います。)
$ aws cloudformation create-stack \
  --stack-name CodeDeployWPStack \
  --template-body file://CodeDeploy_SampleCF_Template.json ¥
  --parameters ParameterKey=InstanceCount,ParameterValue=2 ParameterKey=InstanceType,ParameterValue=t1.micro \
    ParameterKey=KeyPairName,ParameterValue=(keypair-name) ParameterKey=OperatingSystem,ParameterValue=Linux \
    ParameterKey=SSHLocation,ParameterValue=0.0.0.0/0 ParameterKey=TagKey,ParameterValue=Name \
    ParameterKey=TagValue,ParameterValue=mytestfleet \
  --capabilities CAPABILITY_IAM
  (EC2インスタンスを2つ起動します。)
```

## Step 2: Configure your Source Content to Deploy to the Amazon Linux or Red Hat Enterprise Linux Amazon EC2 Instance
開発用の端末にて、CodeDeployにてDeployが可能な形式のWordPressソースコードを作成します。

下記のコマンドを実行すると、WordPressのオリジナルソースコードをダウンロードした上で必要なスクリプトファイルおよびAppSpecファイルが作成されます。

```
wget https://github.com/WordPress/WordPress/archive/master.zip

unzip master -d /tmp/WordPress_Temp
mkdir -p /tmp/WordPress
cp -paf /tmp/WordPress_Temp/WordPress-master/* /tmp/WordPress
rm -rf /tmp/WordPress_Temp
rm -f master

mkdir -p /tmp/WordPress/scripts

cat << EOS > /tmp/WordPress/scripts/install_dependencies.sh
#!/bin/bash
yum groupinstall -y "Web Server" "MySQL Database" "PHP Support"
yum install -y php-mysql
EOS

cat << EOS > /tmp/WordPress/scripts/stop_server.sh
#!/bin/bash
isExistApp=`pgrep httpd`
if [[ -n  \$isExistApp ]]; then
   service httpd stop
fi
isExistApp=`pgrep mysqld`
if [[ -n  \$isExistApp ]]; then
    service mysqld stop
fi
EOS

cat << EOS > /tmp/WordPress/scripts/start_server.sh
#!/bin/bash
service httpd start
service mysqld start
EOS

cat << EOS > /tmp/WordPress/scripts/change_permissions.sh
#!/bin/bash
chmod -R 755 /var/www/html/WordPress
EOS

chmod +x /tmp/WordPress/scripts/*

cat << EOS > /tmp/WordPress/appspec.yml
version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html/WordPress
hooks:
  BeforeInstall:
    - location: scripts/install_dependencies.sh
      timeout: 300
      runas: root
  AfterInstall:
    - location: scripts/change_permissions.sh
      timeout: 300
      runas: root
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 300
      runas: root
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 300
      runas: root
EOS
```

## Step 3: Upload Your WordPress Application to Amazon S3
Step 2にて作成したソースコードをS3にアップロードします。
なお、事前にアップロード先のバケットに対して下記のようなバケットポリシーを設定しておきます。

```
{
  "Statement": [
    {
      "Action": ["s3:PutObject"],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::(bucket-name)/*",
      "Principal": {
        "AWS": [
          "(AWSのアカウントID)"
        ]
      }
    }
  ]
}
```

下記のコマンドを実行することで、CodeDeploy Applicationの作成およびソースコードのpushをします。

```
cd /tmp/WordPress
aws deploy create-application --application-name WordPress_App

aws deploy push \
  --application-name WordPress_App \
  --s3-location s3://bucket-name/WordPressApp.zip \
  --ignore-hidden-files
```

## Step 4: Deploy Your WordPress Application
さいごに、ApplicationをDeployします。

下記コマンドでは、AWSアカウント(123456789012)のService Role(codedeploy)にてDeployment Group(WordPress_DepGroup)を作成します。Deploy対象のEC2インスタンスはNameに"mytestfleet"が指定されたものとなります。

```
aws deploy create-deployment-group \
  --application-name WordPress_App \
 --deployment-group-name WordPress_DepGroup \
  --deployment-config-name CodeDeployDefault.OneAtATime \
  --ec2-tag-filters Key=Name,Value=mytestfleet,Type=KEY_AND_VALUE \
  --service-role-arn arn:aws:iam::123456789012:role/codedeploy
```

つぎに、create-deploymentを実行してDeployを実施します。
```
aws deploy create-deployment \
  --application-name WordPress_App \
  --deployment-config-name CodeDeployDefault.OneAtATime \
  --deployment-group-name WordPress_DepGroup \
  --s3-location bucket=bucket-name,bundleType=zip,key=WordPressApp.zip
```