備忘
要件
Ansible管理ノードに導入されたServerspecを用いて、Ansible Playbookから管理対象ノードに対するテストを行う要件があるとする。
また、Ansibleは管理対象ノードへの接続情報を含むインベントリーを既に持っているとする。
localhostを対象とするインベントリー ⇒ △
Serverspecを実行するのはローカルノードの為、対象が localhostのインベントリーを利用したAnsible Playbook実行、あるいは, hosts: localhost とした Playbook実行が考えられる。
しかしながら、この場合、Serverspec用のテスト対象ノードへの接続情報は別途管理が必要となってしまい、2重管理となる。
管理対象ノードに対するインベントリーとローカル実行の組み合わせ ⇒ ○
それよりは、既に存在する管理対象ノードへの接続情報を含むインベントリーを利用して、情報の重複管理をさけた方がスマート。
リモートホストに対するインベントリーを使用していても、delegate_to: localhostによりローカルノード上でタスクを実行することが可能。
例
Ansible管理ノードに導入されたServerspecにより、Ansibleのインベントリー等における接続情報を利用して、管理対象ノードでのテストを行う場合、以下のように連携可能。
Playbookの例
---
- name: Execute Serverspec tests
hosts: all # <= ここではlocalhostとしない
gather_facts: false
tasks:
- name: Run Serverspec test
delegate_to: localhost # <= ここでlocalhostとする
environment:
TARGET_HOST: "{{ ansible_host }}" # <= ansibleが認識している接続情報を連携
USER: "{{ ansible_user }}" # <= ansibleが認識している接続情報を連携
SSH_KEY: "{{ ansible_private_key_file }}" # <= ansibleが認識している接続情報を連携
SSH_PORT: "{{ ansible_port }}" # <= ansibleが認識している接続情報を連携
command: rspec /path/to/my_spec.rb
テスト対象ノードへの接続情報は環境変数としてServerspecに連携
delegate_to: localhostとしても、ansible_host, ansible_userなどは本来の接続先のまま。
Note
The ansible_host variable and other connection variables, if present, reflects information about the host a task is delegated to, not the inventory_hostname.
Testの例
require 'spec_helper'
set :backend, :ssh
set :host, ENV['TARGET_HOST'] # <= Ansibleにおける接続情報を取り込み
set :ssh_options, user: ENV['USER'], keys: ENV['SSH_KEY'], port: ENV['SSH_PORT'] # <= Ansibleにおける接続情報を取り込み
describe package('httpd'), :if => os[:family] == 'redhat' do
it { should be_installed }
end
describe service('httpd'), :if => os[:family] == 'redhat' do
it { should be_enabled }
it { should be_running }
end
describe port(80), :if => os[:family] == 'redhat' do
it { should be_listening }
end
環境変数として受け取ったテスト対象ノードへの接続情報を利用