EC2へのアプリケーションのデプロイを考えた時に色んな候補があるかと思います。以下にまとまっていました。
最初、OpsWorksを検討したのですが、オートスケーリングに対応していないという点でボツとなりました。。。また、Jenkinsなどを使えば可能だと思いますが、その場合にはJenkinsをSPOFにならないように気をつけたり、AWSと連携するためにごにょごにょするのが面倒かなと思いました。
で、まだtokyoリージョンにはきていませんが、CodeDeployはオートスケーリングが対応しており、どうだろうということで色々試してみたたのでメモ。
今回の例ではGitHubへのpush時にCodeDeployを利用してEC2にWordPressのデプロイを行ってみました。
CodeDeployとは
- アプリケーションのデプロイを行うためのサービス。デプロイするプログラミング言語などに制限はない
- アプリケーションにデプロイに特化した機能なので環境構築などに使うべきではない(やろうと思えばできるけどやらない方が良いと思う)環境構築もしたい場合、ElasticBeanstalkやOpsWorksを考えたほうが良い
- appspec.ymlというファイルにデプロイ時の詳細を記述。デプロイ時の独自のライフサイクルタイミングで任意のシェルスクリプトを実行できる
- 特定のタグが付与されたEC2群もしくはオートスケーリングに紐づくEC2群にデプロイ可能
- 特定のリビジョンに戻ることが可能
- 現在はGitHubとS3と連携が可能(なぜCodeCommitがない??)
- 実行するためにはCodeDeployAgentを対象EC2(にインストールする必要がある
- 対象OSはAmazon Linux、Red Hat Enterprise Linux、Ubuntu Server、Microsoft Windows Server
- CodeDeployエンドポイントと接続する必要があるため、プライベートサブネットの場合などにはNATが必要
前提
- AWS CLIインストール済み
- GitHubのアカウント取得済み
- 2015/7/20現在CodeDeployはtokyoリージョンはないのでus-east1で確認
参考
- Using the AWS CodeDeploy Create Deployment Walkthrough
- Automatically Deploy from GitHub Using AWS CodeDeploy
CodeDeployが使うRoleの作成
Create a Service Role for AWS CodeDeploy
CodeDeploy自体が利用するRoleの設定を行います。
まず、以下のファイルを作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": [
"codedeploy.us-east-1.amazonaws.com",
"codedeploy.us-west-2.amazonaws.com",
"codedeploy.eu-west-1.amazonaws.com",
"codedeploy.ap-southeast-2.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
作成後、以下のコマンドを実行し、CodeDeployDemoというCodeDeploy用のロールを作成します。
$aws iam create-role --role-name CodeDeployDemo --assume-role-policy-document file://CodeDeployDemo-Trust.json
上記コマンド実行後、
"Arn": "arn:aws:iam::hogefuga:role/CodeDeployDemo"
というような形でこのロールのArnが表示されるのでメモしておきます。
また、以下のコマンドを実行し、先ほどのロールがCodeDeployで利用できるように設定します。
$aws iam attach-role-policy --role-name CodeDeployDemo --policy-arn arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole
RDSの作成
WordPressで利用するMySQLをRDSで作成します。
リージョンはus-east1で作成してください。また、次に作成するEC2からの3306ポートで接続できるようなSecurityGroupの設定をしてください。
作成時に設定したユーザー名、パスワード及び作成後のRDSの接続エンドポイントはメモしておいてください。
EC2の起動
Step 1: Launch an Amazon Linux or Red Hat Enterprise Linux Amazon EC2 Instance
- OSはAmazonLinux
- Auto-assign PublicIPを有効にする
- SecurityGroupのInboundでSSHとHTTPを0.0.0.0/0で許可し、Outboundは制限しない
- S3のread権限があるIAMロールを付与すること(CodeDeployAgentのインストールのため)
- NameタグではCodeDeployDemoと設定すること
- UserDataに以下の設定を行う。なお、CodeDeployAgent取得先バケット名はregionによって変わるので注意。また、SQL実行の箇所はユーザー名はroot、パスワードはpassword、RDSのエンドポイントはcodedeploy.cukvcqdui8ox.us-east-1.rds.amazonaws.com という場合の設定となるので適宜変更してください。
#!/bin/bash
# install CodeDeploy agent
yum -y update
yum install -y ruby
yum install -y aws-cli
cd /home/ec2-user
aws s3 cp s3://aws-codedeploy-us-east-1/latest/install . --region us-east-1
chmod +x ./install
./install auto
# install httpd
yum install -y httpd
chkconfig httpd on
service httpd start
# install application dependencies
yum install php php-mysql php-gd php-mbstring -y
yum install mysql -y
#exec sql
mysql -u root -ppassword -h codedeploy.cukvcqdui8ox.us-east-1.rds.amazonaws.com <<EOF
CREATE USER'wordpress-user'@'%' IDENTIFIED BY 'wordpress';
CREATE DATABASE \`wordpress\`;
GRANT ALL PRIVILEGES ON \`wordpress\`.*TO"wordpress-user"@"%";
FLUSH PRIVILEGES;
EOF
起動し、StatsuCheckがrunningになったら、ssh接続し、agentがインストールされているか確認します。
$sudo service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 6975
必要に応じてvar/log/cloud-init-output.log
でのログ確認やその他ミドルウェアの設定も確認してください。
GitHubにCodeDeploy用のWordPressをpushする
以下より、ローカルPCで実施します。
WordPressのソースコードをgit cloneしてきます。
$mkdir -p /tmp/WordPress
$git clone https://github.com/WordPress/WordPress.git /tmp/WordPress
スクリプト配置用のフォルダ作成。
$mkdir -p /tmp/WordPress/scripts
httpdを止めるためのスクリプトを作ります。
#!/bin/bash
isExistApp=`pgrep httpd`
if [[ -n \$isExistApp ]]; then
service httpd stop
fi
httpdを開始するスクリプトも作ります。
#!/bin/bash
service httpd start
パーミッションを変更するスクリプトを作成します。
#!/bin/bash
chown -R apache:apache /var/www/html/WordPress
chmod -R 744 /var/www/html/WordPress
作成したスクリプト群の権限を変更します。
$chmod +x /tmp/WordPress/scripts/*
次にどこにソースコードを配置するのか、またどのライフサイクルタイミングで何をするのかをappsec.ymlに記述します。
version: 0.0
os: linux
files:
- source: /
destination: /var/www/html/WordPress
hooks:
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
appsec.ymlの詳細は以下を参照のこと。
AWS CodeDeploy AppSpec File Reference
次にGithubでリポジトリを作成します。
今回の例ではブラウザから事前に toshihirock/CodeDeployWordPressというリポジトリを作成しました。
リポジトリ作成後、GitHubにコードをpushします。
$cd /tmp/WordPress
$git add .
$git commit -m "add codedeploy scripts"
$git remote rm origin
$git remote add origin https://github.com/toshihirock/CodeDeployWordPress.git
CodeDeployの設定
まずCodeDeployでアプリケーションの作成を行います。以下のコマンドで WordPress_App というアプリケーションを作成します。
$aws deploy create-application --application-name WordPress_App --region us-east-1
次にデプロイメントグループを作成します。本設定ではどのEC2にデプロイするかを設定します。下記例ではEC2のタグでKey=Name、Value=CodeDeployDemoというEC2群にデプロイすることを示す WordPress_DepGroup というデプロイ面とグループを作成しました。
$aws deploy create-deployment-group \
--region us-east-1 \
--application-name WordPress_App \
--deployment-group-name WordPress_DepGroup \
--deployment-config-name CodeDeployDefault.OneAtATime \
--ec2-tag-filters Key=Name,Value=CodeDeployDemo,Type=KEY_AND_VALUE \
--service-role-arn arn:aws:iam::hogefuga:role/CodeDeployDemo
最後にソースコードをデプロイします。--github-location
オプションは適宜自分のリポジトリ名、対象コミットIDに変更してください。
$aws deploy create-deployment \
--region us-east-1 \
--application-name WordPress_App \
--deployment-config-name CodeDeployDefault.OneAtATime \
--deployment-group-name WordPress_DepGroup \
--github-location commitId=74e74ad4e0f80fb91a6034f3be58fce5b45d4a2c,repository=toshihirock/CodeDeployWordPress
デプロイが成功すればデプロイ対象のEC2のPublicIPアドレスを利用して以下のようなURLでアクセスが可能だと思います。
GitHubとの連携を行う
Automatically Deploy from GitHub Using AWS CodeDeploy
まず、IAMでGitHubというユーザーを作成します。なお、ユーザー作成の際に表示されるAccess Key IDとSecret Access keyをメモしておいてください。
また、以下のポリシーを上記ユーザーにCustomPolicyとしてアタッチします。PolicyNameはCodeDeploy-Accessとしました。なお、123ACCOUNTIDという部分は自分のAWSアカウントIDに変更してください。
- IAM->Users->GitHub->InlinePolicies->click here
- Custom Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "codedeploy:GetDeploymentConfig",
"Resource": "arn:aws:codedeploy:us-east-1:123ACCOUNTID:deploymentconfig:*"
},
{
"Effect": "Allow",
"Action": "codedeploy:RegisterApplicationRevision",
"Resource": "arn:aws:codedeploy:us-east-1:123ACCOUNTID:application:WordPress_App"
},
{
"Effect": "Allow",
"Action": "codedeploy:GetApplicationRevision",
"Resource": "arn:aws:codedeploy:us-east-1:123ACCOUNTID:application:WordPress_App"
},
{
"Effect": "Allow",
"Action": "codedeploy:CreateDeployment",
"Resource": "arn:aws:codedeploy:us-east-1:123ACCOUNTID:deploymentgroup:WordPress_App/WordPress_DepGroup"
}
]
}
次にGitHub側の設定をします。AWS CodeDeploy用のサービスを追加します。
- GitHubのページでリポジトリを選択(私の場合、toshihirock/CodeDeployWordPress)
- Settings
- Webhooks and Services
- Add Services->AWS CodeDeploy
以下のように項目を追加します。
次にGitHubのアクセストークンを取得します。
Personal access tokensを表示し、Generate a personal access token を選択し、以下のように設定します。
設定後、トークン情報が表示されるのでメモしておいてください。
先ほどCodeDeployのサービスを設定したページへ再度遷移し、GitHub Auto-Deploymentを追加します。
- GitHubのページでリポジトリを選択(私の場合、toshihirock/CodeDeployWordPress)
- Settings
- Webhooks and Services
- Add Services->GitHub Auto-Deployment
作成後、以下のように2つのサービスが設定された形となっているかと思います。
準備ができたので試しにWordPressリポジトリにからコミットをしてみます。
$cd /tmp/WordPress
$git commit --allow-empty -m "test CodeDeploy"
$git push origin master
$git log -1
commit b74c07c54a747fd9a44be09031bcd272ae749bed
上記実施後、CodeDeployの画面を確認すると先ほどのコミットIDのリビジョンのソースコードがデプロイされたのが分かります。
最後に
今回CodeDeployを試してみましたが、GitHubへのHook時にデプロイできるのは非常に便利に感じました。そしてCodeDeploy自体の管理をしなくて良いというのは非常に楽ですね。
はやくCodeCommitとの連携ができて、VPCエンドポイントにCodeDeployとCodeCommitが出来てプライベートサブネットからも利用できるようになるととても嬉しいです。