Ansibleでは自動化する内容をPlaybookで管理します。
実行ユーザにとっては事前設定を必要とせずこのPlaybookを取得するだけで実行できることが理想的です。
詳細は後述しますが、実行ユーザの事前設定を避けるためにいくつかの準備をしていくとコマンド引数が増えていきます。
ANSIBLE_CONFIG="./ansible.cfg"
ansible-playbook --ssh-common-args="-o StrictHostKeyChecking=no" -i ./hosts TARGET.yml
このようにオプションが増えていくと、オプションが構成管理されないため運用が不安定になっていきます。
安定した運用を維持するためには、オプションも構成管理対象として、以下のコマンドだけでAnsibleを実行できることが理想的です。
ansible-playbook TARGET.yml
以降では、実行ユーザの事前設定を回避し、オプションを構成管理し、ansible-playbook
をシンプルに実行する方法を説明します。
1. Playbookの取得
作成したPlaybookは構成管理し、適切な権限管理のもとワンライナーで取得可能とします。
git clone https://github.com/sonatard/ansible-sample.git
また手順を必ずREADME.md
として記載します。
2. hostsファイルによる実行対象の管理
hostsファイルはデフォルトでは/etc/ansible/hosts
から読み込まれます。
ただしこのファイルで管理する運用にしてしまうと、playbookを実行するユーザが別途hostsファイルを取得して上記のパスに配置しなければなりません。
これを回避するためには、hosts
ファイルをplaybookを管理しているrootに配置します。
ansible-sample
├── README.md
├── ansible.cfg
├── TARGET.yml
├── group_vars
├── host_vars
├── hosts ★
└── roles
以下のように実行可能になります。
ansible-playbook -i ./hosts TARGET.yml
またhostsは毎回同じにもかかわらずコマンド実行のたびに-i ./hosts
オプションを指定したくはありません。
anasible.cfg
を作成し、以下のような設定を追加します。
またPlaybookと同じディレクトリに配置してリポジトリの管理対象にします。
[defaults]
inventory = hosts
ansible-sample
├── README.md
├── ansible.cfg ★
├── TARGET.yml
├── group_vars
├── host_vars
├── hosts
├── ssh_config
└── roles
こうすることで自動的に./hosts
が使われるようになります。
ansible-playbook TARGET.yml
ansible.cfg
ファイルは実行時に指定せずとも自動的に読み込まれます。
正確には、以下の優先順位でansible.cfgは反映されます。
- ANSIBLE_CONFIG環境変数で指定したファイル
- ./ansible.cfg
- $HOME/ansible.cfg
- /etc/ansible/ansible.cfg
3. SSHオプション
SSHの関連オプション
Ansibleを使っているとSSHのオプションを渡したくなることがあります。
例えば開発環境において頻繁にAnsibleのターゲットのIPが変わるような場合に、余計な警告を黙らせるため--ssh-common-args
オプションにStrictHostKeyChecking no
を渡します。
ansible-playbook --ssh-common-args="-o StrictHostKeyChecking=no" TARGET.yml
sshの設定はファイルの分離することが可能です。 ssh_config
ファイルを作り、Playbookと同様のリポジトリで管理します。
Host *
StrictHostKeyChecking no
ansible-sample
├── README.md
├── ansible.cfg
├── TARGET.yml
├── group_vars
├── host_vars
├── hosts
├── ssh_config ★
└── roles
-F
オプションでssh_configを指定可能です。
ansible-playbook --ssh-common-args="-F ssh_config" TARGET.yml
さらに実行のたびに--ssh-common-args=
を指定することを回避します。
ansible.cfg
を作成してssh_args
を設定します。
[ssh_connection]
ssh_args = -F ssh_config
以上で、自動的にssh_config
ファイルが読み込まれます。
ansible-playbook TARGET.yml
4. SSH鍵の管理
Ansibleを実行するターゲットにアクセスするためにはSSHの認証が通らなければいけません。
パスワード認証ではAnsibleの実行が手間になるため基本的には秘密鍵と公開鍵のペアを作成して、公開鍵を対象のサーバに登録し、秘密鍵をAnsible実行環境のユーザの$HOME/.ssh/
に配置します。さらにssh-agent
を利用することでパスフレーズの入力が1度で済むため効率的です。
ssh-agent
はAnsibleに限った話ではないため割愛します。
鍵の登録の作業は実行ユーザごとに必要な作業となります。
そこでAnsibleの実行対象すべてに1度で鍵の登録作業を完了するroleを作成します。
- name: Add user authorized_keys to ${HOME}/.ssh/authorized_keys
authorized_key:
user: "{{ user.name }}"
key: "{{ lookup('file', '/home/user/ssh/id_rsa.pub') }}"
- hosts: all
vars:
user:
name: user_name
pass: password
roles:
- sshkey
公開鍵を登録していない初回は--ask-pass
を指定してSSHのパスワードログインをする必要があります。
TARGET_SERVER=xxx.co.jp
ansible-playbook -i "${TARGET_SERVER}," --ask-pass setup_key.yml
また非推奨ですが、もしplaybookを管理するリポジトリとAnsibleの実行対象が外部からアクセスできないセキュリティが担保された環境に配置されている場合には、パスフレーズが空の秘密鍵と公開鍵をレポシトリに含めることで、完全に事前設定が必要ないポータブルの環境が構築できます。
この場合は、誰かがサーバに公開鍵を1度登録してしまえば、誰でもgit clone
直後にansible-playbook
コマンドが実行可能です。
このときはssh_configにリポジトリ内の秘密鍵のパスを指定します。
Host *
StrictHostKeyChecking no
IdentityFile ./ssh/id_rsa
最後に
自動化ツールの運用、保守
Ansibleに限りませんが自動化ツールをチームで運用する際には、自動化した仕組みを利用するメンバーに説明することがとても重要になります。
自動化環境を構築した担当者は「自動化されているのだから細かい説明はいらないだろう このコマンド打てばこうなるよ 」ということだけ伝えてしまいがちです。
しかしこれでは、他の人がその自動化ツールを使う可能性は下がります。
なぜなら多くの人は得体の知れない自動化ツールを実行することはとても怖く、多少手間だとしても慣れたやり方でやりたがるためです。
また環境を構築した担当者が先程のような発想になるのは、自動化資産の目的を「何も知らない人でも環境を構築できるようにすること」としているためだと思いますが、そうではなく「環境構築をコード化することで手順を明らかにし、チーム全員で自動化資産を運用保守をできる体制を整備する」ことを目的としたほうがいいでしょう。
おわり