Packerを使ったInfrastructure as Code
前回の記事の最後で触れたようにこちらではEC2インスタンスを構築することなく、Packerを使ってAMIの作成を自動で行えるようにします。
Packerについて
PackerはTerraformと同じHashiCorpによって開発されたマシンイメージのオートメーションクリエイトツールです。
AWSやGCPなどのパブリッククラウドのマシンイメージの作成はもちろんDockerイメージやVagrantイメージの構築もできます。そしてPackerではテンプレートと呼ばれるJSONファイル内に、設定しておきたいツールやソフトウェアのインストール指定ができ、Ansibleのような構成管理ツールのような使い方も可能です。
今回はテンプレートファイル内にAnsibleを呼び出して、WordPressが入ったAMIを作成していきたいと思います。
今回の構築結果をまとめたレポジトリ
使用するツール
Packer 1.6.0
PackerでのAMI構築
テンプレートファイル
{
"builders": [
{
"type": "amazon-ebs",
"region": "ap-northeast-1",
"source_ami": "ami-06ad9296e6cf1e3cf",
"instance_type": "t2.micro",
"ssh_username": "ec2-user",
"ami_name": "packer-build-WP {{timestamp}}"
}
],
"provisioners":[
{
"type": "shell",
"inline": [
"sudo yum -y update",
"sudo amazon-linux-extras install -y ansible2"
]
},
{
"type": "ansible-local",
"playbook_file": "../ansible/wordpress.yml",
"playbook_dir": "../ansible"
}
]
}
builders項目でベースとなるEC2インスタンスのAMIを指定しています。この辺はTerraformでの指定とあまり変わりません。
provisionersでは構築したEC2インスタンス内で実行したい処理を記載します。
type:shellの部分はシェルスクリプトを作るイメージで、EC2インスタンスのyum updateと ansibleのインストールをExtras libraryから行うように記述しています。そしてtype:ansible-localと指定している箇所ですが、これはビルドしたEC2インスタンス内でansibleを実行するようにしています。対象のPlaybookですが、playbook_fileを指定することで、ローカルマシン上のPlaybookをEC2インスタンスへコピーしてくれて実行してくれます。
---
- name: Terraformで構築したAmazon LinuxにWordPressをセットアップ
hosts: all
become: true
vars:
db_name: wordpress
db_user: wordpress
db_password: mysQ1InsecureP@ssw0rd
roles:
- name: common
tags:
- common
- name: mariadb
vars:
mariadb_databases:
- name: "{{ db_name }}"
mariadb_users:
- name: "{{ db_user }}"
password: "{{ db_password }}"
priv: "{{ db_name }}.*:ALL"
tags:
- mariadb
- name: php-fpm
vars:
php_fpm_additional_packages:
- php-mysqlnd
tags:
- php-fpm
- name: nginx
vars:
nginx_default_port: 8080
tags:
- nginx
- name: wordpress
vars:
wordpress_db_name: "{{ db_name }}"
wordpress_db_user_name: "{{ db_user }}"
wordpress_db_user_password: "{{ db_password }}"
wordpress_nginx_user: "{{ nginx_user }}"
wordpress_nginx_group: "{{ nginx_group }}"
wordpress_nginx_config_dir: "{{ nginx_config_dir }}"
wordpress_php_fpm_config_dir: "{{ php_fpm_config_dir }}"
tags:
- wordpress
使ったPlaybookは前回記事で使ったものをそのまま流用しました。hostsはallを指定していますが、Packerではローカルでしかansibleを実行できないので、特に修正する必要はありませんでした。またこのPlaybookはrolesで別のPlaybookを呼びだしており、これ単体でWordPressを導入できません。ここでplaybook_dirで本来ローカルマシン上でAnsibleを実行するディレクトリを指定することでディレクトリ配下のAnsible関連の設定ファイルをまるごとEC2インスタンスへコピーしてくれます。
packer validate コマンドでテンプレートファイルの構文チェックを行い、何も表示されなかったらエラーがないのでpacker buildでPackerを実行します。
$ packer build WPinstalled.json
amazon-ebs: output will be in this color.
==> amazon-ebs: Prevalidating any provided VPC information
==> amazon-ebs: Prevalidating AMI Name: packer-build-WP 1595171359
amazon-ebs: Found Image ID: ami-06ad9296e6cf1e3cf
==> amazon-ebs: Creating temporary keypair: packer_5f14621f-c926-b1c2-f66e-207c16cf5861
==> amazon-ebs: Creating temporary security group for this instance: packer_5f146221-de2b-574b-5354-dcf808abbc0c
==> amazon-ebs: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> amazon-ebs: Launching a source AWS instance...
==> amazon-ebs: Adding tags to source instance
amazon-ebs: Adding tag: "Name": "Packer Builder"
amazon-ebs: Instance ID: i-0c47de24934148f0f
==> amazon-ebs: Waiting for instance (i-0c47de24934148f0f) to become ready...
==> amazon-ebs: Using ssh communicator to connect: 54.238.217.172
==> amazon-ebs: Waiting for SSH to become available...
==> amazon-ebs: Connected to SSH!
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
==> amazon-ebs: Another app is currently holding the yum lock; waiting for it to exit...
==> amazon-ebs: The other application is: yum
==> amazon-ebs: Memory : 117 M RSS (334 MB VSZ)
==> amazon-ebs: Started: Sun Jul 19 15:10:05 2020 - 00:03 ago
==> amazon-ebs: State : Running, pid: 3541
amazon-ebs: Resolving Dependencies
amazon-ebs: --> Running transaction check
amazon-ebs: ---> Package amazon-ssm-agent.x86_64 0:2.3.714.0-1.amzn2 will be updated
amazon-ebs: ---> Package amazon-ssm-agent.x86_64 0:2.3.1319.0-1.amzn2 will be an update
amazon-ebs: ---> Package bind-export-libs.x86_64 32:9.11.4-9.P2.amzn2.0.3 will be updated
amazon-ebs: ---> Package bind-export-libs.x86_64 32:9.11.4-9.P2.amzn2.0.4 will be an update
amazon-ebs: ---> Package bind-libs.x86_64 32:9.11.4-9.P2.amzn2.0.3 will be updated
amazon-ebs: ---> Package bind-libs.x86_64 32:9.11.4-9.P2.amzn2.0.4 will be an update
amazon-ebs: ---> Package bind-libs-lite.x86_64 32:9.11.4-9.P2.amzn2.0.3 will be updated
amazon-ebs: ---> Package bind-libs-lite.x86_64 32:9.11.4-9.P2.amzn2.0.4 will be an update
amazon-ebs: ---> Package bind-license.noarch 32:9.11.4-9.P2.amzn2.0.3 will be updated
amazon-ebs: ---> Package bind-license.noarch 32:9.11.4-9.P2.amzn2.0.4 will be an update
amazon-ebs: ---> Package bind-utils.x86_64 32:9.11.4-9.P2.amzn2.0.3 will be updated
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
amazon-ebs: ---> Package system-release.x86_64 1:2-11.amzn2 will be updated
amazon-ebs: ---> Package system-release.x86_64 1:2-12.amzn2 will be an update
amazon-ebs: --> Finished Dependency Resolution
amazon-ebs: Dependencies Resolved
amazon-ebs:
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜yum updateの実行〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
amazon-ebs: ================================================================================
amazon-ebs: Package Arch Version Repository Size
amazon-ebs: ================================================================================
amazon-ebs: Installing:
amazon-ebs: kernel x86_64 4.14.181-142.260.amzn2 amzn2-core 21 M
amazon-ebs: Updating:
amazon-ebs: amazon-ssm-agent x86_64 2.3.1319.0-1.amzn2 amzn2-core 21 M
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜amazon-linux-extras install -y ansible2の実行〜〜〜〜
amazon-ebs: ================================================================================
amazon-ebs: Package Arch Version Repository Size
amazon-ebs: ================================================================================
amazon-ebs: Installing:
amazon-ebs: ansible noarch 2.9.9-1.amzn2 amzn2extra-ansible2 17 M
amazon-ebs: Installing for dependencies:
amazon-ebs: libtomcrypt x86_64 1.18.2-1.amzn2.0.1 amzn2extra-ansible2 409 k
amazon-ebs: libtommath x86_64 1.0.1-4.amzn2.0.1 amzn2extra-ansible2 36 k
amazon-ebs: python-keyczar noarch 0.71c-2.amzn2 amzn2extra-ansible2 218 k
amazon-ebs: python2-crypto x86_64 2.6.1-13.amzn2.0.3 amzn2extra-ansible2 476 k
amazon-ebs: python2-ecdsa noarch 0.13.3-1.amzn2.0.1 amzn2extra-ansible2 94 k
amazon-ebs: python2-httplib2 noarch 0.18.1-3.amzn2 amzn2extra-ansible2 125 k
amazon-ebs: python2-paramiko noarch 1.16.1-3.amzn2.0.2 amzn2extra-ansible2 259 k
amazon-ebs: sshpass x86_64 1.06-1.amzn2.0.1 amzn2extra-ansible2 22 k
amazon-ebs:
amazon-ebs: Transaction Summary
amazon-ebs: ================================================================================
amazon-ebs: Install 1 Package (+8 Dependent packages)
amazon-ebs:
amazon-ebs: Total download size: 19 M
amazon-ebs: Installed size: 110 M
amazon-ebs: Downloading packages:
amazon-ebs: --------------------------------------------------------------------------------
amazon-ebs: Total 42 MB/s | 19 MB 00:00
amazon-ebs: Running transaction check
amazon-ebs: Running transaction test
amazon-ebs: Transaction test succeeded
amazon-ebs: Running transaction
amazon-ebs: Installing : sshpass-1.06-1.amzn2.0.1.x86_64 1/9
amazon-ebs: Installing : python2-httplib2-0.18.1-3.amzn2.noarch 2/9
amazon-ebs: Installing : libtommath-1.0.1-4.amzn2.0.1.x86_64 3/9
amazon-ebs: Installing : libtomcrypt-1.18.2-1.amzn2.0.1.x86_64 4/9
amazon-ebs: Installing : python2-crypto-2.6.1-13.amzn2.0.3.x86_64 5/9
amazon-ebs: Installing : python-keyczar-0.71c-2.amzn2.noarch 6/9
amazon-ebs: Installing : python2-ecdsa-0.13.3-1.amzn2.0.1.noarch 7/9
amazon-ebs: Installing : python2-paramiko-1.16.1-3.amzn2.0.2.noarch 8/9
amazon-ebs: Installing : ansible-2.9.9-1.amzn2.noarch 9/9
amazon-ebs: Verifying : python2-ecdsa-0.13.3-1.amzn2.0.1.noarch 1/9
amazon-ebs: Verifying : libtommath-1.0.1-4.amzn2.0.1.x86_64 2/9
amazon-ebs: Verifying : python2-crypto-2.6.1-13.amzn2.0.3.x86_64 3/9
amazon-ebs: Verifying : ansible-2.9.9-1.amzn2.noarch 4/9
amazon-ebs: Verifying : python-keyczar-0.71c-2.amzn2.noarch 5/9
amazon-ebs: Verifying : libtomcrypt-1.18.2-1.amzn2.0.1.x86_64 6/9
amazon-ebs: Verifying : python2-paramiko-1.16.1-3.amzn2.0.2.noarch 7/9
amazon-ebs: Verifying : python2-httplib2-0.18.1-3.amzn2.noarch 8/9
amazon-ebs: Verifying : sshpass-1.06-1.amzn2.0.1.x86_64 9/9
amazon-ebs:
amazon-ebs: Installed:
amazon-ebs: ansible.noarch 0:2.9.9-1.amzn2
amazon-ebs:
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜ここからAnsibleのPlaybookを実行〜〜〜〜〜〜〜〜〜〜〜〜〜
==> amazon-ebs: Provisioning with Ansible...
amazon-ebs: Uploading Playbook directory to Ansible staging directory...
amazon-ebs: Creating directory: /tmp/packer-provisioner-ansible-local/5f14621f-4587-4d3a-ef49-9a0f31fbb57d
amazon-ebs: Uploading main Playbook file...
amazon-ebs: Uploading inventory file...
amazon-ebs: Executing Ansible: cd /tmp/packer-provisioner-ansible-local/5f14621f-4587-4d3a-ef49-9a0f31fbb57d && ANSIBLE_FORCE_COLOR=1 PYTHONUNBUFFERED=1 ansible-playbook /tmp/packer-provisioner-ansible-local/5f14621f-4587-4d3a-ef49-9a0f31fbb57d/wordpress.yml --extra-vars "packer_build_name=amazon-ebs packer_builder_type=amazon-ebs packer_http_addr=ERR_HTTP_ADDR_NOT_IMPLEMENTED_BY_BUILDER -o IdentitiesOnly=yes" -c local -i /tmp/packer-provisioner-ansible-local/5f14621f-4587-4d3a-ef49-9a0f31fbb57d/packer-provisioner-ansible-local296006708
amazon-ebs:
amazon-ebs: PLAY [Terraformで構築したAmazon LinuxにWordPressをセットアップ] *****************************
amazon-ebs:
amazon-ebs: TASK [Gathering Facts] *********************************************************
==> amazon-ebs: [WARNING]: Platform linux on host 127.0.0.1 is using the discovered Python
==> amazon-ebs: interpreter at /usr/bin/python, but future installation of another Python
==> amazon-ebs: interpreter could change this. See https://docs.ansible.com/ansible/2.9/referen
amazon-ebs: ok: [127.0.0.1]
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜Playbook実行完了〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
amazon-ebs: PLAY RECAP *********************************************************************
amazon-ebs: 127.0.0.1 : ok=31 changed=22 unreachable=0 failed=0 skipped=2 rescued=1 ignored=0
amazon-ebs:
==> amazon-ebs: Stopping the source instance...
amazon-ebs: Stopping instance
==> amazon-ebs: Waiting for the instance to stop...
==> amazon-ebs: Creating AMI packer-build-WP 1595171359 from instance i-0c47de24934148f0f
amazon-ebs: AMI: ami-094fbef15a2274cf2
==> amazon-ebs: Waiting for AMI to become ready...
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
==> amazon-ebs: Deleting temporary security group...
==> amazon-ebs: Deleting temporary keypair...
Build 'amazon-ebs' finished.
==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:
ap-northeast-1: ami-094fbef15a2274cf2
最後にAMIが作成されてAMIのIDが表示されていることを確認できました。
AMI画面にも作成されていることが確認できました。このAMIを基にTerraformでEC2インスタンスを構築してWordPressがちゃんと導入されているか確認します。
AMIを基にEC2インスタンスが構築されてIPアドレスをブラウザから確認してWordPressのインストール画面を見ることを確認できました。
感想
Packerをただ単にビルドするだけでしたら公式AMIと変わらないAMIができます。
テンプレートファイル内に設定したいprovisinionを記述することで自分だけのオリジナルのAMIを作成することができます。上手く活用することで複数のAWSアカウント内でAMIを通じて同じ環境構築が可能になりますので、今後も理解を深めていきたいと思います。