私はansibleプレイブックを持っています。そこでは、あるマシンで登録した変数を別のマシンで利用できるようにしたいと考えています。
私の場合、localhost
、この場合はgit rev-parse --abbrev-ref HEAD
でコマンドを実行したいので、現在のgitブランチとsha1をメモして、この出力を登録します。セカンドプレイでmain
グループのマシンを操作するときに、後でそれを参照できます。
ただし、localhostに変数を登録する方法は明確ではないため、mainから変数にアクセスできます。セカンドプレイで変数にアクセスしようとすると、次のメッセージが表示されます。
TASK: [debug msg={{ app_git_sha1.stdout }}] ***********************************
fatal: [main] => One or more undefined variables: 'app_git_sha1' is undefined
これが私が使っている遊びです。私がやるべきことは明らかですか?
---
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: register current branch
command: git rev-parse --abbrev-ref HEAD
register: git_branch
Sudo: no
when: vagrant
tags:
- debugsha
- debug: msg={{ git_branch.stdout }}
tags:
- debugsha
- name: register the SHA1 of the branch being deployed
command: git rev-parse Origin/{{ git_branch.stdout }}
register: app_git_sha1
Sudo: no
tags:
- slack
- debugsha
- debug: msg={{ app_git_sha1.stdout }}
tags:
- debugsha
- hosts: main
Sudo: yes
roles:
- role: productscience.deploy_user
# TODO reprovision using these roles, for consistency
# - role: app.essentials
# - role: zenoamaro.postgresql
- role: productscience.papertrailapp
- role: jdauphant.nginx
tasks:
- include: setup.yml
# - include: db.yml
- name: checkout source control when deploying to remote servers
include: source.yml
when: not vagrant
tags:
- deploy
- include: Django.yml
tags:
- deploy
- name: include vagrant specific dependencies for local development
include: vagrant.yml
when: vagrant
handlers:
- name: restart postgres
Sudo: yes
service: name=postgresql state=restarted
- name: start restart uwsgi
Sudo: yes
service: name={{ app }} state=restarted
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: register the SHA1 of the branch being deployed
when: not vagrant
command: git rev-parse Origin/{{ git_branch }}
register: git_sha
tags:
- slack
- name: Send notification message via Slack all options
when: not vagrant
tags:
- slack
local_action:
module: slack
token: "{{ wof_slack_token }}"
msg: "Deployment of `{{ git_branch }}` to {{ app_url }} completed with sha `{{ git_sha.stdout }}`"
channel: "#wof"
username: "Ansible deploy-o-tron"
実行中の問題は、あるホストのファクト/変数を別のホストのファクト/変数から参照しようとしていることです。 Ansibleでは、ホストlocalhost
に割り当てられた変数app_git_sha1
は、ホストmain
または他のホストに割り当てられた変数app_git_sha1
とは異なることに留意する必要があります。あるホストのファクト/変数に別のホストからアクセスする場合は、hostvars
変数を介して明示的に参照する必要があります。これについてもう少し議論があります この質問で 。
次のようなプレイブックがあるとします。
- hosts: localhost
tasks:
- command: /bin/echo "this is a test"
register: foo
- hosts: localhost
tasks:
- debug: var=foo
これは、両方の再生で変数localhost
のホストlocalhosts
およびfoo
のインスタンスを参照しているため機能します。このプレイブックの出力は次のようなものです。
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [command /bin/echo "this is a test"] ************************************
changed: [localhost]
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [debug var=foo] *********************************************************
ok: [localhost] => {
"var": {
"foo": {
"changed": true,
"cmd": [
"/bin/echo",
"this is a test"
],
"delta": "0:00:00.004585",
"end": "2015-11-24 20:49:27.462609",
"invocation": {
"module_args": "/bin/echo \"this is a test\"",
"module_complex_args": {},
"module_name": "command"
},
"rc": 0,
"start": "2015-11-24 20:49:27.458024",
"stderr": "",
"stdout": "this is a test",
"stdout_lines": [
"this is a test"
],
"warnings": []
}
}
}
このPlaybookを少し変更して、あるホストで最初のプレイを実行し、別のホストで2番目のプレイを実行すると、発生したエラーが発生します。解決策は、Ansibleの組み込みhostvars
変数を使用して、2番目のホストが最初のホスト変数を明示的に参照するようにすることです。したがって、最初の例を次のように変更します。
- hosts: localhost
tasks:
- command: /bin/echo "this is a test"
register: foo
- hosts: anotherhost
tasks:
- debug: var=foo
when: foo is defined
- debug: var=hostvars['localhost']['foo']
when: hostvars['localhost']['foo'] is defined
このプレイブックの出力は、foo
がホストanotherhost
によって定義されていないため、最初のタスクがスキップされることを示しています。ただし、2番目のタスクは、変数localhosts
のfoo
のインスタンスを明示的に参照しているため成功します。
TASK: [debug var=foo] *********************************************************
skipping: [anotherhost]
TASK: [debug var=hostvars['localhost']['foo']] **************************
ok: ['anotherhost'] => {
"var": {
"hostvars['localhost']['foo']": {
"changed": true,
"cmd": [
"/bin/echo",
"this is a test"
],
"delta": "0:00:00.005950",
"end": "2015-11-24 20:54:04.319147",
"invocation": {
"module_args": "/bin/echo \"this is a test\"",
"module_complex_args": {},
"module_name": "command"
},
"rc": 0,
"start": "2015-11-24 20:54:04.313197",
"stderr": "",
"stdout": "this is a test",
"stdout_lines": [
"this is a test"
],
"warnings": []
}
}
}
したがって、簡単に言うと、main
プレイブックの変数参照を変更して、localhost
変数をこの方法で参照する必要があります。
{{ hostvars['localhost']['app_git_sha1'] }}
たとえば、K8Sトークンとハッシュをマスターからワーカーに渡すには。
- name: "Cluster token"
Shell: kubeadm token list | cut -d ' ' -f1 | sed -n '2p'
register: K8S_TOKEN
- name: "CA Hash"
Shell: openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
register: K8S_MASTER_CA_HASH
- name: "Add K8S Token and Hash to dummy Host"
add_Host:
name: "K8S_TOKEN_HOLDER"
token: "{{ K8S_TOKEN.stdout }}"
hash: "{{ K8S_MASTER_CA_HASH.stdout }}"
- name:
debug:
msg: "[Master] K8S_TOKEN_HOLDER K8S token is {{ hostvars['K8S_TOKEN_HOLDER']['token'] }}"
- name:
debug:
msg: "[Master] K8S_TOKEN_HOLDER K8S Hash is {{ hostvars['K8S_TOKEN_HOLDER']['hash'] }}"
- name:
debug:
msg: "[Worker] K8S_TOKEN_HOLDER K8S token is {{ hostvars['K8S_TOKEN_HOLDER']['token'] }}"
- name:
debug:
msg: "[Worker] K8S_TOKEN_HOLDER K8S Hash is {{ hostvars['K8S_TOKEN_HOLDER']['hash'] }}"
- name: "Kubeadmn join"
Shell: >
kubeadm join --token={{ hostvars['K8S_TOKEN_HOLDER']['token'] }}
--discovery-token-ca-cert-hash sha256:{{ hostvars['K8S_TOKEN_HOLDER']['hash'] }}
{{K8S_MASTER_NODE_IP}}:{{K8S_API_SERCURE_PORT}}
同じホストでも、異なるプレイで同様の問題が発生しました。覚えておくべきことは、プレイ全体で持続するものの変数ではなく、事実です。ここに私が問題を回避する方法があります。
#!/usr/local/bin/ansible-playbook --inventory=./inventories/ec2.py
---
- name: "TearDown Infrastructure !!!!!!!"
hosts: localhost
gather_facts: no
vars:
aws_state: absent
vars_Prompt:
- name: "aws_region"
Prompt: "Enter AWS Region:"
default: 'eu-west-2'
tasks:
- name: Make vars persistant
set_fact:
aws_region: "{{aws_region}}"
aws_state: "{{aws_state}}"
- name: "TearDown Infrastructure hosts !!!!!!!"
hosts: monitoring.ec2
connection: local
gather_facts: no
tasks:
- name: set the facts per Host
set_fact:
aws_region: "{{hostvars['localhost']['aws_region']}}"
aws_state: "{{hostvars['localhost']['aws_state']}}"
- debug:
msg="state {{aws_state}} region {{aws_region}} id {{ ec2_id }} "
- name: last few bits
hosts: localhost
gather_facts: no
tasks:
- debug:
msg="state {{aws_state}} region {{aws_region}} "
結果として
Enter AWS Region: [eu-west-2]:
PLAY [TearDown Infrastructure !!!!!!!] ***************************************************************************************************************************************************************************************************
TASK [Make vars persistant] **************************************************************************************************************************************************************************************************************
ok: [localhost]
PLAY [TearDown Infrastructure hosts !!!!!!!] *********************************************************************************************************************************************************************************************
TASK [set the facts per Host] ************************************************************************************************************************************************************************************************************
ok: [XXXXXXXXXXXXXXXXX]
TASK [debug] *****************************************************************************************************************************************************************************************************************************
ok: [XXXXXXXXXXX] => {
"changed": false,
"msg": "state absent region eu-west-2 id i-0XXXXX1 "
}
PLAY [last few bits] *********************************************************************************************************************************************************************************************************************
TASK [debug] *****************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"changed": false,
"msg": "state absent region eu-west-2 "
}
PLAY RECAP *******************************************************************************************************************************************************************************************************************************
XXXXXXXXXXXXX : ok=2 changed=0 unreachable=0 failed=0
localhost : ok=2 changed=0 unreachable=0 failed=0