ALBにつなげるEC2を自動スケールさせます。またデプロイは複数のEC2に自動でデプロイしたいので、CodeDeployを使ってみました。CodeDeployは、S3にプッシュして、それを利用してデプロイするようにしました。CodeDeployが自動デプロイする際、プロジェクトルートにある appspac.yml
というファイルの内容に従います。下記のような感じにしましした。
version: 0.0 os: linux files: - source: / destination: /home/ec2-user/app/hoge permissions: - object: /home/ec2-user/app/hoge pattern: "**" owner: ec2-user group: ec2-user hooks: BeforeInstall: - location: deploy/remove.sh timeout: 30 runas: ec2-user AfterInstall: - location: deploy/set_env.sh timeout: 5 runas: ec2-user ApplicationStart: - location: deploy/reload_pm2.sh timeout: 60 runas: ec2-user
ちなみに、app/hoge
配下にでデプロイするプログラムはAdonis.jsのアプリです。CodeDeployは、デプロイ先にファイルがあるとエラーになるようです。ですので、BeforeInstall
時にapp/hoge
内を空にしてます。set_env.sh
では、下記のような感じで、環境に応じて.env
ファイルを作成しています。ApplicationStart
時に、pm2 resurrect
を実行して、Adonis.jsアプリを起動しています。ただ、結構デプロイ完了までに時間がかかりますね。特にテスト環境では頻繁にgit pullしたくなりそうなので、テスト環境では基本的にはgitを使うことになるのかなと思いました。
#!/bin/bash Pro="hoge" Region="us-east-1" InstanceID=`curl -s http://169.254.169.254/latest/meta-data/instance-id/` TagName=`aws ec2 describe-instances --region ${Region} --instance-ids ${InstanceID} --query 'Reservations[].Instances[].Tags[?Key==\`Name\`].Value' --output text` cd /home/ec2-user/app/hoge rm .env if [ $TagName = $Pro ]; then ln -s .env.pro .env else ln -s .env.dev .env fi
あとはプライベートIPアドレスが、デプロイの度に変わります。Blue/Greenデプロイを利用しなければ変わらないで済むかもしれませんが、Blue/Greenの方が安全そうだし、ロールバックできるしいいかなと思いました。あとは自動スケール設定にするとどちらにしても、IPアドレスは変わるのかなと思います。基本的に変わっても全く問題ないのですが、sshの際にちょっとめんどくさいかなと思ったので、下記も作りました。
#/bin/bash Region="us-east-1" TagNameOfPro="pro-hoge" TagNameOfDev="dev-hoge" HostOfPro="pro-hoge" HostOfDev="dev-hoge" if [ $1 = "pro" ]; then echo "Env: pro" TagName=$TagNameOfPro Host=$HostOfPro else echo "Env: dev" TagName=$TagNameOfDev Host=$HostOfDev fi echo TagName: $TagName echo Host: $Host IP=`aws ec2 describe-instances --region ${Region} --query 'Reservations[].Instances[].[PrivateIpAddress][0][0]' --filters "Name=tag:Name,Values=${TagName}" "Name=instance-state-code,Values=16"` echo IP: $IP ssh -o HostName=${IP} ${Host}
上記の$Hostは、./ssh/configで設定しているHostになります。例えば下記のようになっています。
Host pro-hoge HostName 192.168.0.0 User ec2-user ProxyCommand ssh -W %h:%p bastion Port 22 IdentityFile ~/.ssh/pro-hoge.pem LocalForward 3337 pro-hoge-cluster.cluster-***********.us-east-1.rds.amazonaws.com:3306
ssh接続する際に基本的にはこの設定を使いつつ、-oオプションを使って、HostName(IPアドレス)だけは、コマンド実行時に直接指定するようにしています。そのIPアドレスを、現在稼働中の環境から取得しています。 ec2 describe-instances
の filters
の instance-state-code
というのは、稼働中とか停止中とかを数値で表しているものだそうです。稼働中の場合は16だそうです。
デプロイコマンド
S3にプッシュして、その後でデプロイを開始します。
#/bin/bash if [ $1 = "pro" ]; then aws deploy push --application-name hoge-pro --s3-location s3://hoge-revision/hoge-pro.zip --source . aws deploy create-deployment --application-name hoge-pro --deployment-group-name hoge-pro --s3-location bucket=hoge-revision,key=hoge-pro.zip,bundleType=zip else aws deploy push --application-name hoge-dev --s3-location s3://hoge-revision/hoge-dev.zip --source . aws deploy create-deployment --application-name hoge-dev --deployment-group-name hoge-dev --s3-location bucket=hoge-revision,key=hoge-dev.zip,bundleType=zip fi