Packer + Ansible で GCP のイメージを作成してみた
概要
名称 | 役割 |
---|---|
Packer | AMIなどイメージを作成するためのツール |
Ansible | OS・ミドルウェアの導入・設定を行うための構成管理ツール |
Terraform | インフラの構成・設定をコード化するためのツール |
- Packer + Ansible = インスタンス〜ミドルウェアまでを設定
- Terraform = インフラとしての構成(ネットワーク、ロードバランサ、インスタンスなど)全体を設定
イメージとしては Packer + Ansible でインスタンス・テンプレートを作成し、Terraform でVPC全体像をデプロイする形になる。
Packer
インストール
公式のダウンロードページからバイナリをダンロードして ${HOME}/bin
配下に展開する。
$ mkdir ~/bin ; cd $_ $ curl -O https://releases.hashicorp.com/packer/1.2.4/packer_1.2.4_linux_amd64.zip $ unzip packer_1.2.4_linux_amd64.zip $ rm packer_1.2.4_linux_amd64.zip $ echo PATH=${HOME}/bin:${PATH} >> ~/.bashrc $ source ~/.bashrc $ packer version Packer v1.2.4
- ドキュメントの指定するまま AWS で AMI の作成を行っても良いんだけど、個人的にはGCPのほうが好きなのでGCPで試してみる。
- GCPのインスタンスイメージを1から作る方法もあるが、公式のドキュメントにあった Builder のドキュメント の通り、GCP上にすでに用意されているイメージを利用する。
- GCP上でサービスアカウントを作成・認証ファイル(JSON)の取得し、CloudSDK (gcloudコマンド) を利用できる状態にしとく。
最初のデプロイ
Packer の基本的な設定を作成してデプロイしてみる。 下記JSONで指定する source_image は GCPのコンソール > Compute Engine > イメージ
または gcloud compute images list
で確認できる。
$ mkdir ~/packer-example ; cd $_ $ vi base.json
{ "builders": [ { "type": "googlecompute", "account_file": "account.json", "project_id": "my project", "source_image": "centos-7-v20180523", "ssh_username": "packer", "zone": "asia-northeast1-a" } ] }
作成したJSONで色々試してみる。
$ packer inspect base.json #<-作成したJSONで何が実施されるのか内容を表示 $ packer validate base.json #<-バリデーションチェック $ packer build base.json ... googlecompute output will be in this color. ==> googlecompute: Checking image does not exist... ==> googlecompute: Creating temporary SSH key for instance... ==> googlecompute: Using image: centos-7-v20180523 ==> googlecompute: Creating instance... googlecompute: Loading zone: asia-northeast1-a googlecompute: Loading machine type: n1-standard-1 googlecompute: Requesting instance creation... googlecompute: Waiting for creation operation to complete... googlecompute: Instance has been created! ==> googlecompute: Waiting for the instance to become running... googlecompute: IP: xxx.xxx.xxx.xxx ==> googlecompute: Waiting for SSH to become available... ==> googlecompute: Connected to SSH! ==> googlecompute: Deleting instance... googlecompute: Instance has been deleted! ==> googlecompute: Creating image... ==> googlecompute: Deleting disk... googlecompute: Disk has been deleted! Build 'googlecompute' finished. ==> Builds finished. The artifacts of successful builds are: --> googlecompute: A disk image was created: packer-1527668955 #<-packer-1527668955 というイメージが作成された
実際に GCPコンソール > ComputeEngine > イメージ
を確認すると packer-1527668955
というイメージが作成されていた。
JSONの細かいオプションは 公式のドキュメント を見るとわかる。
例えば source_image_family
を指定することで常に centos-7
の最新版を利用したり、image_name
で生成されるイメージの名前を指定することができる。
Packer と Ansible の連携
Packer に読み込ませる JSON は下記のように4つの項目で設定する。 variable
と provisioners
を利用することで Ansible などと連携したイメージの作成が行える。
{ "variables": [ { // 変数 } ], "builders": [ { // AWS, GCP などデプロイ先の設定 } ], "provisioners": [ { // Ansible, ShellScript ほか } ], "post-processors": [ { // 後処理 } ] }
作成例
公式ドキュメントのProvisionerの項目を見れば大体わかるけど、Ansible についてはインスタンスのローカル・リモートからの両方に対応してみるみたい。
作成例は下記の通り。 sshd の sftp-server
にオプションを追加しているのは、公式のドキュメントに注意書きがあったため。
{ "builders": [ { "type": "googlecompute", "account_file": "account.json", "project_id": "my project", "source_image_family": "centos-7", "ssh_username": "packer", "zone": "asia-northeast1-a" } ], "provisioners": [ { "type": "shell", "inline": [ "sudo yum -y update", "sudo yum -y --enablerepo=epel install ansible", "sudo sed -i '/sftp-server$/s/$/ -e/' /etc/ssh/sshd_config", "sudo systemctl restart sshd" ] }, { "type": "ansible", "playbook_file": "apache.yml" } ] }
同じディレクトリに Ansbile の Playbook を置く。 become: true
で root で実行されるようにする。
--- - hosts: all become: true tasks: - name: install apache yum: name=httpd - name: create index.html shell: echo "Hello World!" > /var/www/html/index.html - name: apache restart service: name=httpd state=restarted enabled=yes
この状態で packer validate
を実行すると ansible-playbook
が見つからないと怒られるので、別途Ansibleを入れてから行う (自分は pyenv で入れた)
$ pyenv virtualenv 3.6.5 ansible $ pyenv local ansible $ pip install ansible $ packer validate base.json Template validated successfully.
そして packer inspect
で反映される内容を確認してからデプロイしてみる。
$ packer inspect base.json $ packer build base.json ... #-> yum 〜 ansible の実行までの出力がわかる
んで、インスタンスを作成する際にカスタムイメージを選択してインスタンスを作成・起動し、Apache が起動していることを確認するとこまでできた。
あとは Packer のTemplates とかドキュメント見たり、やりたいことを整理して Ansible で頑張る感じかな。
参考URL
- Packer : Docuemnt : Getting Started
- Packer : Google Compute Builder
- Packer+AnsibleによるAMIの作成 (Developers.IO)
- Packerを使って1コマンドで本番サーバと開発サーバ (のVMイメージ)を作る話 (Qiita)
その他
作成したイメージを利用して、インスタンス・テンプレートを作成して〜とかは Terraform で行うので、次は Terraform を頑張る。
以上