Home > Enterprise >  Loop inside an Ansible module
Loop inside an Ansible module

Time:05-30

I am trying to create an ECS task definition using the community.aws.ecs_taskdefinition I wrote something like this:

- name: Create task definition   
  community.aws.ecs_taskdefinition:
    containers:
    - name: First_container
      << container definition >>
    
    - name: "{{ item.service }}"
      essential: true
      image: "{{ user_info.account }}.dkr.ecr.{{ AWS_REGION }}.amazonaws.com/{{ app_name }}-{{ item.service }}"
      environment:
        "{{ item.env_var }}"
      portMappings:
      - containerPort: "{{ item.port_a }}"
        hostPort: "{{ item.port_b }}" 
      with_items:
         - "{{ parameters }}"
     

Basically I want to create one task definition with the first container plus all the other defined in parameters. Unfortunately if I put the with_item as above, it doesn't work and if I put it at the same level of containers it will create many revision of the same task definition and each revision will have the first container and only one of those defined in parameters.

Is there any way to achieve this?

edit: for clarification basically parameter is a list of dictionaries like:

parameters : [{service:"service1",env_var:"something",port_a:80,port_b:80} ,
           { service:"service2",env_var:"somethingelse",port_a:3000,port_b:3000}]

what I want to achieve is the same as:

- name: Create task definition   
  community.aws.ecs_taskdefinition:
    containers:
    - name: First_container
      << container definition >>
    
    - name: "service1"
      essential: true
      image: "{{ user_info.account }}.dkr.ecr.{{ AWS_REGION }}.amazonaws.com/{{ app_name }}-service1"
      environment:
        env_var: "something" 
      portMappings:
      - containerPort: 80
        hostPort: 80 
    - name: "service2"
      essential: true
      image: "{{ user_info.account }}.dkr.ecr.{{ AWS_REGION }}.amazonaws.com/{{ app_name }}-service2"
      environment:
        env_var: "somethingelse" 
      portMappings:
      - containerPort: 3000
        hostPort: 3000

but because parameters can have many services, I would like to have a loop to deal with it. hope is more clear.

CodePudding user response:

You cannot access {{ parameters }} variables directly inside a playbook.

Workaround will be:

loop:
  - { service: "service1", env_var: "something", port_a: 80, port_b: 80 }
  - { service: "service2", env_var: "somethingelse", port_a: 3000, port_b: 3000 }

or else register the variables in inventory file or add it to your playbook. Refer

CodePudding user response:

you could try to create a variable and include it in task:

  tasks:
    - set_fact:
        containers: "{{ container0   other_containers.names}}" 
      vars:
        parameters : [{"service":"service1", "env_var":"something", "port_a":80, "port_b":80} ,
                      { "service":"service2", "env_var":"somethingelse", "port_a":3000, "port_b":3000}]      
        container0:
          - name: "First_container"
            other_param: "otherrrrrrs"
        other_containers: >-
            { "names": [
            {%- for p in parameters -%}
            {"name": {
                        "essential": true,
                        "environment": "{{ p.env_var }}",
                        "portMappings": [{ "containerPort": "{{ p.port_a }}", "hostPort": "{{ p.port_b }}" }]  
                      }
            } {{ "" if loop.last else "," }}          
            {%- endfor -%}
            ]}
            
    - debug:
        msg: "{{ containers }}"

    - name: Create task definition   
      community.aws.ecs_taskdefinition:
        containers: "{{ containers }}"
  • Related