見出し画像

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が表示されていることを確認できました。

画像2

AMI画面にも作成されていることが確認できました。このAMIを基にTerraformでEC2インスタンスを構築してWordPressがちゃんと導入されているか確認します。

画像3

画像3

AMIを基にEC2インスタンスが構築されてIPアドレスをブラウザから確認してWordPressのインストール画面を見ることを確認できました。

感想

Packerをただ単にビルドするだけでしたら公式AMIと変わらないAMIができます。
テンプレートファイル内に設定したいprovisinionを記述することで自分だけのオリジナルのAMIを作成することができます。上手く活用することで複数のAWSアカウント内でAMIを通じて同じ環境構築が可能になりますので、今後も理解を深めていきたいと思います。

この記事が気に入ったらサポートをしてみませんか?