この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
どうも今年の目標はベンチプレス150kgのオンジーです。
AnsibleのplaybookをEC2 Image Builderで使ってみました。
なおAnsible、Image Builderの基本的な使い方についてはある程度知っている前提で書かれています。最後に入門記事のリンクを載せていますのでご参考ください。
やってみた
AWSが公開しているサンプルを使って実行してみます。
内容としてはAmazon Linux2にapacheをインストールしてHello worldと書かれたトップページを作成するというシンプルなものです。
playbookの中身
my-playbook.ymlの中身です。
- name: Apache Hello World
hosts: 127.0.0.1
gather_facts: false
connection: local
tasks:
- name: Install Apache
yum:
name: httpd
state: latest
- name: Create a default page
shell: echo "<h1>Hello world from EC2 Image Builder and Ansible</h1>" > /var/www/html/index.html
- name: Enable Apache
service: name=httpd enabled=yes state=started
従来のAnsibleではsshやWinRMでリモートホストにアクセスしミドルウェアのインストールや設定ファイルの更新を行いますが
Image Builder 内で Ansible を実行する際はAMIを作成するEC2上で実行することになるのでローカルホスト上で実行するように設定する必要があります。
次の部分がローカルでの実行を強制している箇所になります。
hosts: 127.0.0.1
gather_facts: false
connection: local
このmy-playbook.ymlを事前にS3バケットにアップロードしておきます。
componentの中身
Image Builderで実行するビルドコンポーネント(component.yml)ですが以下の流れになっています。
- Ansible をインストール
- S3 バケットからplaybookをダウンロード
- playbook実行
- playbook削除(クリーンアップ)
- Apache が正しいコンテンツを返していることを検証
ここでは解体して説明していますので全文は先ほどのGitHubよりご確認ください。
まずはドキュメントの説明とbuildフェーズの指定をします。
name: 'Ansible Playbook Execution on Amazon Linux 2'
description: 'This is a sample component that demonstrates how to download and execute an Ansible playbook against Amazon Linux 2.'
schemaVersion: 1.0
phases:
- name: build
steps:
Amazon Linux 2ではAmazon Linux Extrasを使ってAnsibleをインストールできるので、ExecuteBashアクションを使ってインストールします。
- name: InstallAnsible
action: ExecuteBash
inputs:
commands:
- sudo amazon-linux-extras install -y ansible2
S3Download アクションを使用してplaybookをダウンロードし、tmpフォルダに保存します。
S3バケットを指定している箇所は先ほどmy-playbook.ymlをアップロードしたバケットのパスに書き換えてください。
- name: DownloadPlaybook
action: S3Download
inputs:
- source: 's3://mybucket/my-playbook.yml'
destination: '/tmp/my-playbook.yml'
ExecuteBinary アクションを使用して Ansible を起動し、playbookに記載されている作業を実行します。
ここでは前段のステップから入力値や出力値を参照できる機能 chaining を使用しています。詳しくは下記をご参照ください。
{{build.DownloadPlaybook.inputs[0].destination}}}は、'/tmp/my-playbook.yml'を指定していることになります。
値の入力ミスによるビルドの失敗を避けるために、このように参照でS3Download先のパスを取得しています。
- name: InvokeAnsible
action: ExecuteBinary
inputs:
path: ansible-playbook
arguments:
- '{{build.DownloadPlaybook.inputs[0].destination}}'
Ansibleを実行したのでダウンロードしたplaybookを削除しています。
ここでも同様に参照によって取得したパスでExecuteBashアクションを実行しています。
- name: DeletePlaybook
action: ExecuteBash
inputs:
commands:
- rm '{{build.DownloadPlaybook.inputs[0].destination}}'
ここまででbuildフェーズが終わったのでvalidateフェーズに移ります。
curlを使ってApacheが正しいコンテンツで応答することを確認しています。
- name: validate
steps:
- name: ValidateResponse
action: ExecuteBash
inputs:
commands:
- curl -s http://127.0.0.1 | grep "Hello world from EC2 Image Builder and Ansible"
validateフェーズが実行されると、EC2が停止しAMIが作成されます。
Image Builderは、このAMIを使用して新しいEC2インスタンスを起動するtestフェーズに移行します。
そのためtestフェーズでもvalidate フェーズと同じ curl コマンドを使用して同様に正しいコンテンツが返ってくるかを確認しています。
※注意:S3バケットへのアクセス権限が必要です。
Image BuilderではAMIをビルドおよびテストする一時的なEC2にIAMロールを設定するのですがそこにplaybookを配置したS3へのアクセス権限が必要です。
ポリシーは下記の様なイメージです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
完成したAMIを起動してみる
出来上がったAMIからEC2を起動してみました。
トップページが表示されました!やったね!
おわり
apacheのインストールなどもちろんビルドコンポーネントで記述はできるのですがAnsibleを既に使っていた場合はその資産を使いたいですよね。
上記の手順で実行できますのでお試しください。
参考
合わせて読みたい
Ansible
Image Builder