key value pair mapping in ansible to pass run the role with the appropriate value

我的梦境 提交于 2021-02-08 08:09:04

问题


I am new to ansible. I have a small scenario. So I pass the name of the branch using ansible when I run it. In my play book I have:

# Deploy docker container
- include_role:
    name: devops/deployment.docker
  vars:
    docker_name: "docker name is based on the branch id develop dev if UAT test if master then it should be prod"
  when: build_type in "develop master UAT"

and in devops/deployment.docker I have a role which deploy a docker image.

- name: push docker container
  docker_image:
    name: "{{ docker.registery }}/docker_name"
    source: build
    build: 
      nocache: true
      path: "{{ travis.base_build_path }}"
    tag: "{{ ucd.component_version }}"
    push: yes

So I send build_type as develop,UAT or master when I run the ansible this role will be called. Now there is an issue:

I need to build my image based on the branch so the code needs to be intelligent and when I send develop it should go search for the key assigned to develop and get the related docker name and build it. something similar to this:

{
 develop: {
  dockerName:dev
 },
 master: {
  dockerName: prod
  },
 UAT: {
   dockerName: test
 }
}

If anyone help me how to do it in ansible I really appreciate it


回答1:


TLDR;

- name: push docker container
  vars:
    docker_name: "{{ vars[build_type].dockerName }}"
  docker_image:
    name: "{{ docker.registery }}/{{ docker_name }}"
    source: build
    build: 
      nocache: true
      path: "{{ travis.base_build_path }}"
    tag: "{{ ucd.component_version }}"
    push: yes

Vars notation

Ansible has 2 notations to access dict items:

  • The dot notation: {{ my_var.my_key.my_subkey }}
  • The bracket notation: {{ my_var['my_key']['my_subkey'] }}

You can mix those two notations as you wish

  • {{ my_var.my_key['my_subkey'] }}
  • {{ my_var['my_key'].my_subkey }}

Note that lists can be accessed the same way using their index:

  • {{ my_list.0 }}
  • {{ my_list[0] }}

Vars "access point"

Each of your environment definition is a first level var. You can normally call those vars in a template expression directly, e.g. {{ master.dockerName }}. But those vars are also available through the first level vars dict so the following is exactly equivalent {{ vars.master.dockerName }}.

Finally...

Knowing the above and that you are sending the name of the relevant key in the build_type variable, you can get the expected value with: {{ vars[build_type].dockerName }}


Unrelated to your current question

Concerning your include_role condition:

when: build_type in "develop master UAT"

Note that this will work for the value "develop" as you expect, but will also match for "AT", "mast", "devel" or even "op mas". That might break the rest of your operations in case of a typo.

To make sure you match the exact word, put your matches in a list and the comparison will move from "is it a substring of" to "is it an element of"

when: build_type in ["develop", "master", "UAT"]



回答2:


Here is something that works, but there are several ways this could be achieved.

Assuming you are passing variables from the command line while running ansible-playbook.

This would be your command, which you might be knowing already.

ansible-playbook mydocker-playbook.yml --extra-vars "build_type=develop"

Following is an example how you could achieve this.

mydocker-playbook.yaml

---
- name: Docker deployment
  hosts: devops
  become: yes
  roles:
    - devops-role

And your task could be something like this

- name: push docker container
  docker_image:
    name: "{{ docker.registery }}/{{item.name}}"
    source: build
    build: 
      nocache: true
      path: "{{ travis.base_build_path }}"
    tag: "{{ ucd.component_version }}"
    push: yes
  when: build_type == item.type
  with_items:
    - { name: "dev", type: "develop" }
    - { name: "master", type: "prod" }
    - { name: "UAT", type: "test" }

The task iterates over the given list. But executes only when the build_type is one of the values of type. And assigns your docker name with {{item.name}} i.e. either dev, or master, or UAT.

Again, there are several ways we can do this, this is just one of them.

Hope this is helpful.



来源:https://stackoverflow.com/questions/59773518/key-value-pair-mapping-in-ansible-to-pass-run-the-role-with-the-appropriate-valu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!