Packer、AnsibleによるAWS上での本番/ステージング環境用AMIの作成
次に、Packer及びAnsibleを使用してAWS上にEC2のAMIを作成する手順を紹介します。
事前に、AWS上で以下の作業を実施しておいてください。
- IAMユーザーの作成(EC2関連のポリシーを許可しておき、アクセスキー/シークレットアクセスキーを取得しておく)
- キーペアの作成
- 作成したキーペアを~/.ssh/に保存
- VPCの作成(InternetGatewayのアタッチ含む)
- サブネットの作成(RouteTableの設定含む、パブリックなサブネット)
インストール
ここでは同じくMacを対象として、Packerが動作する環境の構築方法についてご説明します。本稿では、Packer:1.3.2での実行例をご紹介します。
Packerは以下のコマンドでインストールします。
Packerのインストール
brew install packer
Packerの設定
今回想定するディレクトリ構成は以下のとおりです。
PROJECT_ROOT
├── vagrant
│ └── provisioning
│ ├── packer_webserver_playbook.yml // Packerでprovisionする際のplaybook
│ ├── group_vars
│ │ └── all.yml // Ansible全体をスコープとした変数
│ └── roles // Playbookて定義されたRole
│ │── common // 共通のタスク
│ │ └── tasks
│ │ │── main.yml
│ │ └── install_common_tools.yml
│ │── user_setup // ユーザー関連のタスク
│ │ │── tasks
│ │ │ │── main.yml
│ │ │ └── add_user.yml
│ │ └── templates
│ │ └── default_user_sudoers.j2
│ └── web // Webサーバ関連のタスク
│ │── tasks
│ │ │── main.yml
│ │ └── install_nginx.yml
│ │── templates
│ │ │── nginx.conf.j2
│ │ └── virtual.conf.j2
│ └── vars
│ └── main.yml
├── packer
│ └── ec2_webserver.json
└── app
└── public
└── index.html
以下の手順で構築していきます。
- AWSのIAMユーザーのプロファイル設定
- Packerの設定ファイルの作成
- Packerの実行
1. AWSのIAMユーザーのプロファイル設定
事前に作成しておいたIAMユーザーのアクセスキー/シークレットアクセスキーを実行するローカルPCに設定しておきます(設定はローカルPCのユーザのホームディレクトリ以下であることに注意してください)。
[sample] output = text region = ap-northeast-1
[sample] aws_access_key_id = アクセスキー aws_secret_access_key = シークレットアクセスキー
これで、sampleプロファイルでAWS CLIが実行できるようになります。
2. Packerの設定ファイルの作成
Packerに、実行する環境や内容を記載したJSONファイルを読み込ませることで、EC2インスタンスをプロビジョニングし、AMIを作成します。
ここで作成するpacker/ec2_webserver.jsonはVagrantで言うところのVagrantfileに該当します。
{
"variables": {
"home": "{{ env `HOME` }}"
},
"builders": [{
"profile": "sample",
"type": "amazon-ebs",
"region": "ap-northeast-1",
"source_ami": "ami-e99f4896",
"instance_type": "t2.micro",
"ssh_username": "ec2-user",
"ssh_keypair_name": "キーペア名",
"ssh_private_key_file": "{{ user `home` }}/.sshキーペア名.pem",
"ami_name": "{{isotime \"20060102-0304\"}}_sample_webserver_image",
"vpc_id": "作成したVPCのID",
"subnet_id": "作成したサブネットのID",
"associate_public_ip_address": true
}],
"provisioners": [{
"type": "ansible",
"playbook_file": "../vagrant/provisioning/packer_webserver_playbook.yml",
"extra_arguments": [
"--extra-vars",
"{ project: {name: 'sample'}, hostname: 'www.sample.test'}"
]
}]
}
| 項目 | 内容 |
|---|---|
| builders.profile | 先程設定したAWSのプロファイル |
| builders.source_ami | プロビジョニングするAMIのID |
| builders.instance_type | プロビジョニングを実施する際のEC2インスタンスタイプ(多くの場合はt2.microでOK) |
| builders.ami_name | プロビジョニングを実施した後に生成されるAMIの名前 |
| provisioners.type | ここではAnsibleを使用 |
| provisioners.playbook_file | Ansible Playbookへのパス |
| provisioners.extra_arguments | provisionersに渡す引数(ここではAnsibleで使用する変数を渡している) |
最後に、Packerでプロビジョニングを実施する際のPlaybookを作成します。
- hosts: all
user: ec2-user
become: yes
vars:
is_vagrant: False
roles:
- common
- user_setup
- web
内容はVagrantのPlaybookの時とほぼ同じですが、以下の指定をすることでRoleの中のタスクでVagrantの時と分岐できるようにしています。
- userがec2-user
- is_vagrantをFalse
3. Packerの実行
では実際にPackerを使用して、AMIを作成します。
cd packer packer build ec2_webserver.json
成功すると、標準出力の最後に以下が出力されます。
・・・ Build 'amazon-ebs' finished. ==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: ap-northeast-1: ami-xxxxxxxxxxxxxxx
AWSのマネジメントコンソールで確認すると、以下のようなAMIができていると思います。
この様にAnsibleでVagrantがきちんと動く環境を作っておくと、Packerで同じ設定のEC2のAMIが簡単に作成でき、開発環境とほぼ同じサーバのイメージをAWSの作成することができます。
最後に
本稿では、Ansible、Vagrant、Packerを用いた開発環境/本番/ステージング環境のサーバ構築についてご説明させて頂きました。
実際にはWebサーバだけでなく、さまざまなパッケージや設定が入りますが、今回ご紹介した内容の応用でできることが多いと思います。
IaaC(Infrastructure as a Code)とまではいかなくとも、最も工数のかかるサーバの構築をコード化することで以下の利点があります。
- 秘伝のタレでない、再現性のある構築手順を確立できる
- 一度作ってしまえば、コマンド一つで環境ができる
- 繰り返し使えることで、OSやミドルのアップデートが容易
- 新規でプロジェクトにアサインされたメンバに容易に開発環境を提供できる
- 開発で使用した環境とほぼ同じ環境をAWS上で構成できる
これら利点によって、開発におけるインフラ構築コスト削減が促進されると幸いです。
