skip to Main Content

I have the following data which is provided as extra vars.

TCP,22,22,10.10.10.10/0
TCP,8080,8080,0.0.0.0/0

So, as:

--extra-vars 'rules="TCP,22,22,10.10.10.10/0nTCP,8080,8080,0.0.0.0/0"'

How can I create multiple rules block using Jinja based on the above CSV data?

Update: I need to have one static rule and rest using dynamic rule if the variable rules is supplied. If the rules extra vars isn’t supplied then I want only the static rule to be present.

- name: create ec2 security group
  # create a security group for the vpc
  amazon.aws.ec2_group:
    vpc_id: "{{ vpc_id }}"
    region: "{{ cloud_region }}"
    state: "present"
    name: "testing_sg_ansible"
    description: "testing_sg_ansible"
    tags:
      Name: "testing_sg_ansible"
    rules:
    - proto: tcp          # Static rule
      from_port: 8085
      to_port: 8085
      cidr_ip: "10.10.10.0/24"
    - proto: TCP          # Dynamic rules using extra vars
      from_port: 22
      to_port: 22
      cidr_ip: 10.10.10.10/0
    - proto: TCP
      from_port: 8080
      to_port: 8080
      cidr_ip: 0.0.0.0/0

2

Answers


  1. Chosen as BEST ANSWER

    The following worked for me. purge_rules: no needs to be set otherwise dynamic rule will be overwritten.

     - name: create ec2 security group
        # create a security group for the vpc
        amazon.aws.ec2_group:
          vpc_id: "{{ vpc_id }}"
          region: "{{ cloud_region }}"
          state: "present"
          name: "{{ sg_name }}"
          description: "Security Group {{ sg_name }}"
          tags:
            Name: "{{ sg_name }}"
          rules: >-                       # Dynamic rule
            {{
              rules.splitlines()
              | map('split', ',')
              | json_query("[*].{
                proto: [0],
                from_port: [1],
                to_port: [2],
                cidr_ip: [3]
              }")
            }}
        when: rules is defined
        register: security_group_results
    
    
      - name: update Ec2 security group
        # update security group for the vpc
        amazon.aws.ec2_group:
          vpc_id: "{{ vpc_id }}"
          region: "{{ cloud_region }}"
          state: "present"
          name: "{{ sg_name }}"
          description: "Security Group {[ sg_name }}"
          tags:
            Name: "{{ sg_name }}"
          purge_rules: no             # This is important so it doesn't overwrite above rule.
          rules:                      # Static rule
          - proto: tcp
            from_port: 8086
            to_port: 8086
            cidr_ip: "10.10.10.0/24"
    

  2. One way you could achieve this is by using JMESPath capabilities and a multiselect hash.

    - name: create ec2 security group for the vpc
      amazon.aws.ec2_group:
        vpc_id: "{{ vpc_id }}"
        region: "{{ cloud_region }}"
        state: "present"
        name: "testing_sg_ansible"
        description: "testing_sg_ansible"
        tags:
          Name: "testing_sg_ansible"
        rules: >-   
          {{
            rules.splitlines()
            | map('split', ',')
            | json_query("[*].{
              proto: [0],
              from_port: [1],
              to_port: [2],
              cidr_ip: [3]
            }")
          }}
    

    A playbook, run with the extra variables, this way:

    ansible-playbook play.yml 
      --extra-vars 'rules="TCP,22,22,10.10.10.10/0nTCP,8080,8080,0.0.0.0/0"'
    

    Would create a rules parameter looking like your expected result:

    rules:
    - cidr_ip: 10.10.10.10/0
      from_port: '22'
      proto: TCP
      to_port: '22'
    - cidr_ip: 0.0.0.0/0
      from_port: '8080'
      proto: TCP
      to_port: '8080'
    

    As an example, given the task:

    - debug:
        msg:
          rules: >-
            {{
              rules.splitlines()
              | map('split', ',')
              | json_query("[*].{
                proto: [0],
                from_port: [1],
                to_port: [2],
                cidr_ip: [3]
              }")
            }}
    

    Run with:

    ansible-playbook play.yml 
      --extra-vars 'rules="TCP,22,22,10.10.10.10/0nTCP,8080,8080,0.0.0.0/0"'
    

    Would yield:

    ok: [localhost] => 
      msg:
        rules:
        - cidr_ip: 10.10.10.10/0
          from_port: '22'
          proto: TCP
          to_port: '22'
        - cidr_ip: 0.0.0.0/0
          from_port: '8080'
          proto: TCP
          to_port: '8080'
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search