Ssh秘密鍵ファイルのansibleプレイブックをコーディングするときに、1つの構成の問題が発生しました。
私たちが知っているように、静的インベントリサーバーのホストサーバー、IP、関連するsshプライベートキーとの組み合わせをansible hostsファイルで定義できます。
しかし、動的インベントリサーバーでそれを定義する方法がわかりません。
例:
---
- hosts: tag_Name_server1
gather_facts: no
roles:
- role1
- hosts: tag_Name_server2
gather_facts: no
roles:
- roles2
以下のコマンドは、そのプレイブックを呼び出すために使用されます。
ansible-playbook test.yml -i ec2.py --private-key ~/.ssh/SSHKEY.pem
私の質問は:
コメントしてくださってありがとうございます
TL; DR: 'tag_Name_server1'はグループであるため、グループ変数ファイルにキーファイルを指定します。
注: EC2外部インベントリスクリプト を使用していると仮定しています。他の動的インベントリアプローチを使用している場合は、このソリューションを微調整する必要があります。
これは私が何ヶ月も苦労しており、何度も苦労してきた問題であり、ブライアン・コカの提案 here のおかげでようやく解決策を見つけました。秘Theは、Ansibleのグループ変数メカニズムを使用して、作業しているマシンの正しいSSHキーファイルを自動的に渡すことです。
EC2インベントリスクリプトは、ホストを参照するために使用できるさまざまなグループを自動的に設定します。プレイブックでこれを使用しています。最初のプレイでは、Ansibleに「role1」を「tag_Name_server1」グループ全体に適用するように指示しています。 Ansibleに、「tag_Name_server1」グループ内の任意のホストに特定のSSHキーを使用するように指示します。これは、グループ変数ファイルが入る場所です。
プレイブックが「my-playbooks」ディレクトリにあると仮定して、「group_vars」ディレクトリの下に各グループのファイルを作成します。
my-playbooks
|-- test.yml
+-- group_vars
|-- tag_Name_server1.yml
+-- tag_Name_server2.yml
これで、プレイブックでこれらのグループを参照するたびに、Ansibleは適切なファイルをチェックし、そこで定義した変数をロードします。
各グループvarファイル内で、グループ内のホストへの接続に使用するキーファイルを指定できます。
# tag_Name_server1.yml
# --------------------
#
# Variables for EC2 instances named "server1"
---
ansible_ssh_private_key_file: /path/to/ssh/key/server1.pem
これで、プレイブックを実行すると、正しいキーが自動的に選択されるはずです!
移植性のために環境変数を使用する
多くの異なるサーバー(ローカル、リモートビルドサーバーなど)でプレイブックを実行することが多いので、物事をパラメーター化するのが好きです。固定パスを使用するのではなく、SSHキーが格納されているディレクトリを指すSSH_KEYDIRと呼ばれる環境変数があります。
この場合、グループvarsファイルは代わりに次のようになります。
# tag_Name_server1.yml
# --------------------
#
# Variables for EC2 instances named "server1"
---
ansible_ssh_private_key_file: "{{ lookup('env','SSH_KEYDIR') }}/server1.pem"
さらなる改善
おそらくこれを改善することができるきちんとした方法がたくさんあります。 1つには、各グループに使用するキーを手動で指定する必要があります。 EC2インベントリスクリプトには各サーバーで使用されるキーペアに関する詳細が含まれているため、おそらくスクリプト自体から直接キー名を取得する方法があります。その場合、キーが配置されているディレクトリを(上記のように)提供し、インベントリデータに基づいて正しいキーを選択させることができます。
この問題に対して見つけることができる最良の解決策は、ansible.cfgで秘密鍵ファイルを指定することです(通常、プレイブックと同じフォルダーに保存します)。
[defaults]
inventory=ec2.py
vault_password_file = ~/.vault_pass.txt
Host_key_checking = False
private_key_file = /Users/eric/.ssh/secret_key_rsa
ただし、プレイブック内のすべてのホストに対してプライベートキーをグローバルに設定します。
注:キーファイルへのフルパスを指定する必要があります-〜user/.ssh/some_key_rsaは黙って無視されます。
コマンドを実行するときに直接使用するキーを簡単に定義できます。
ansible-playbook \
\ # Super verbose output incl. SSH-Details:
-vvvv \
\ # The Server to target: (Keep the trailing comma!)
-i "000.000.0.000," \
\ # Define the key to use:
--private-key=~/.ssh/id_rsa_ansible \
\ # The `env` var is needed if `python` is not available:
-e 'ansible_python_interpreter=/usr/bin/python3' \ # Needed if `python` is not available
\ # Dry–Run:
--check \
deploy.yml
コピーペースト:
ansible-playbook -vvvv --private-key=/Users/you/.ssh/your_key deploy.yml
次の構成を使用しています。
#site.yml:
- name: Example play
hosts: all
remote_user: ansible
become: yes
become_method: Sudo
vars:
ansible_ssh_private_key_file: "/home/ansible/.ssh/id_rsa"
同様の問題があり、ec2.pyのパッチとec2.iniにいくつかの構成パラメーターを追加することで解決しました。パッチはec2_key_nameの値を取得し、それにssh_key_pathをプレフィックスとして付け、最後にssh_key_suffixを追加し、この値としてansible_ssh_private_key_fileを書き出します。
次の変数を新しい「ssh」セクションのec2.iniに追加する必要があります(デフォルトが環境に一致する場合、これはオプションです)。
[ssh]
# Set the path and suffix for the ssh keys
ssh_key_path = ~/.ssh
ssh_key_suffix = .pem
Ec2.pyのパッチは次のとおりです。
204a205,206
> 'ssh_key_path': '~/.ssh',
> 'ssh_key_suffix': '.pem',
422a425,428
> # SSH key setup
> self.ssh_key_path = os.path.expanduser(config.get('ssh', 'ssh_key_path'))
> self.ssh_key_suffix = config.get('ssh', 'ssh_key_suffix')
>
1490a1497
> instance_vars["ansible_ssh_private_key_file"] = os.path.join(self.ssh_key_path, instance_vars["ec2_key_name"] + self.ssh_key_suffix)