web-dev-qa-db-fra.com

Comment définir une variable pour qu'elle persiste entre les jeux dans ansible?

J'ai un livre de jeu ansible, dans lequel j'aimerais qu'une variable que je m'inscrive sur une machine soit disponible sur une autre.

Dans mon cas, j'aimerais lancer une commande sur localhost, dans ce cas git rev-parse --abbrev-ref HEAD, afin que je puisse noter la branche actuelle de git, et sha1, et enregistrer cette sortie, afin de pouvoir y faire référence ultérieurement lorsque je travaillerai sur une machine du groupe main lors de la deuxième lecture.

Cependant, je ne sais pas comment enregistrer une variable sur localhost, je peux donc y accéder depuis main. Lorsque j'essaie d'accéder à la variable lors de la deuxième lecture, je reçois le message suivant:

TASK: [debug msg={{ app_git_sha1.stdout }}] ***********************************
fatal: [main] => One or more undefined variables: 'app_git_sha1' is undefined

Voici le jeu que j'utilise. Y a-t-il quelque chose d'évident que je devrais faire?

---
- 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"
51
Chris Adams

Le problème que vous rencontrez est que vous essayez de référencer les faits/variables d'un hôte à partir de ceux d'un autre hôte. Vous devez garder à l'esprit que dans Ansible, la variable app_git_sha1 assigné à l'hôte localhost est distinct de la variable app_git_sha1 attribué à l'hôte main ou à tout autre hôte. Si vous souhaitez accéder à des faits/variables d'un hôte à partir d'un autre hôte, vous devez le référencer explicitement via la variable hostvars. Il y a un peu plus de discussion à ce sujet dans cette question .

Supposons que vous ayez un livre de lecture comme celui-ci:

- hosts: localhost
  tasks:   
    - command: /bin/echo "this is a test"
      register: foo


- hosts: localhost
  tasks:
    - debug: var=foo

Cela fonctionnera parce que vous faites référence à l'instance de l'hôte localhost et localhosts de la variable foo dans les deux lectures. La sortie de ce livret ressemble à ceci:

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": []
        }
    }
}

Si vous modifiez légèrement ce livre de jeu pour exécuter le premier jeu sur un hôte et le second sur un hôte différent, vous obtiendrez l'erreur que vous avez rencontrée. La solution consiste à utiliser la variable intégrée hostvars d'Ansible afin que le deuxième hôte fasse explicitement référence à la première variable d'hôtes. Alors modifiez le premier exemple comme ceci:

- 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

La sortie de ce classeur montre que la première tâche est ignorée car foo n'est pas défini par l'hôte anotherhost. Mais la deuxième tâche réussit car elle fait explicitement référence à l'occurrence de la variable localhosts de la variable 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": []
        }
    }
}

Donc, en un mot, vous voulez modifier les références de variable dans votre playbook main pour référencer les variables localhost de cette manière:

{{ hostvars['localhost']['app_git_sha1'] }}
90
Bruce P

Utiliser un hôte factice et ses variables

Par exemple, passer le jeton K8S et le hachage du maître aux ouvriers.

Sur le maître

- 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'] }}"

Sur le travailleur

- 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}}
28
mon

J'ai eu des problèmes similaires avec le même hôte, mais dans différentes pièces. Ce qu'il faut retenir, ce sont des faits et non des variables, ce qui reste persistant d'une pièce à l'autre. Voici comment je contourne le problème.

#!/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}} "

résulte en

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
12
krad