Packerで作るrbenv&CodeDeploy エージェント入りAMI

はじめに

おはようございます、加藤です。RailsのアプリケーションをCodeDeployを使ってデプロイする事を想定しAMIをPackerで作成してみました。
GithubとCircleCIを使ってリポジトリにPushすると自動で作成される仕組みを作っています。

前提

Githubの基本的な操作(commit, push, merge)ができる事を前提にしています。必要に応じてググるなど対応してください。

リポジトリ作成

GitHubで新規リポジトリを作成します。ブラウザでアクセスして作成してください。
私はaws-ami-codedeploy-railsという名前で作りました。

初回コミットを完了させておきます。

mkdir aws-ami-codedeploy-rails
cd aws-ami-codedeploy-rails
echo "# aws-ami-codedeploy-rails" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:kmd2kmd/aws-ami-codedeploy-rails.git
git push -u origin master

開発ブランチを作成して切り替えておきます。まだ、プッシュはしません。

git checkout -b dev

以降はこのリポジトリ内で作業を行います。

Packerの作成

今回、AMIにインストールしたい物は下記です。

  • Ruby & Rails
  • CodeDeploy Agent

これをPackerを使ってセットアップしましょう。

├── .circleci
│   └── config.yml
├── README.md
├── scripts
│   ├── common.sh
│   ├── rbenv.sh
│   └── ruby.sh
└── template.json

template.json

最新のAMIを参照する様にした程度で特別な設定は行っていません。

scripts/common.sh

パッケージの最新化とCodeDeployエージェントをインストールしています。
ruby, wgetをインストールしていますが、これは公式ドキュメントのインストール手順に従っているためです。

Amazon Linux または RHEL 用の AWS CodeDeploy エージェントのインストールまたは再インストール - AWS CodeDeploy

scripts/rbenv.sh

rbenvをインストールしてPATHの設定を行っています。

scripts/ruby.sh

rbenvで指定バージョンのRubyをインストールします。

CircleCIの作成

.circleci/config.yml

CicleCIの定義です。Packerが予めインストールされたDockerイメージを使用しています。
masterブランチ以外の場合はブランチ名を、masterブランチの場合はprdを環境変数ENVにセットします。
バリデーションを行った後に、ビルドを実行します。

CircleCIへ登録

CircleCIのアカウントがない場合は作成してください。私はGithubアカウントを使用してサインアップしました。

CircleCIにリポジトリを登録します。左メニューにある歯車アイコンのSETTINGSを開いてください。
Projectsをクリックすると、連携されたGithubのリポジトリ一覧が表示されます。対象のリポジトリを探し、歯車アイコンをクリックします。

Environment Variablesを開いてください、Add VariableからAWS認証情報を環境変数にセットします。

セットが完了したら、Follow Projectをクリックしてください。

ビルド

Githubにプッシュしましょう。

git push -u origin dev

JOBSを開くとdevブランチで成功している事を確認できました。

AMIが作成されているか確認します。

AMIを起動してcodedeploy-agentの動作と、rbenvがインストールしているrubyを確認します。

[ec2-user@ip-10-0-0-134 ~]$ systemctl status codedeploy-agent
● codedeploy-agent.service - AWS CodeDeploy Host Agent
   Loaded: loaded (/usr/lib/systemd/system/codedeploy-agent.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu aws-ami-codedeploy-rails-2019-01-17 10:04:20 UTC; 6min ago
  Process: 2649 ExecStart=/bin/bash -a -c [ -f /etc/profile ] && source /etc/profile; /opt/codedeploy-agent/bin/codedeploy-agent start (code=exited, status=0/SUCCESS)
 Main PID: 2808 (ruby)
   CGroup: /system.slice/codedeploy-agent.service
           ├─2808 codedeploy-agent: master 2808
           └─3265 codedeploy-agent: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller of master 2808

Jan 17 10:04:19 ip-172-31-6-55.ap-northeast-1.compute.internal systemd[1]: Starting AWS CodeDeploy Host Agent...
Jan 17 10:04:20 ip-172-31-6-55.ap-northeast-1.compute.internal systemd[1]: Started AWS CodeDeploy Host Agent.
Jan 17 10:04:26 ip-10-0-0-134.ap-northeast-1.compute.internal bash[2649]: Started master 2808 with 1 children
[ec2-user@ip-10-0-0-134 ~]$ rbenv versions
* system (set by /home/ec2-user/.rbenv/version)
  2.4.5

dev→masterにマージします。JOBSを開くとmasterブランチでも成功している事を確認します。

AMIもできています。

あとがき

AMIをCI/CDしてみました。作成したAMIをこの段階でテストする必要があるかは組織体制や要件に応じて検討してください。テストする場合は下記のブログが参考になります。
PackerによるAMIのテスト考 (2016年度編) | DevelopersIO