Webux Lab - Blog
Webux Lab Logo

Webux Lab

By Studio Webux

Search

By Tommy Gingras

Last update 2022-09-23

ToolAnsible

This snippet is useful when you want to load conditional environment variables, especially used with the shell module or with Serverless Module.

---
- name: Test
  hosts: localhost
  connection: local
  gather_facts: no

  tasks:
    # NOTE: This set fact is useless in a sense that it is only for demonstration
    - name: Set environment variables; it should only have AWS_PROFILE, AWS_REGION
      set_fact:
        env_vars:
          AWS_ACCESS_KEY_ID: "{{ assumed_role.sts_creds.access_key if assumed_role is defined else omit }}"
          AWS_SECRET_ACCESS_KEY: "{{ assumed_role.sts_creds.secret_key if assumed_role is defined else omit }}"
          AWS_SESSION_TOKEN: "{{ assumed_role.sts_creds.session_token if assumed_role is defined else omit }}"
          AWS_REGION: "{{ aws_region }}"
          AWS_PROFILE: "{{ aws_profile if assumed_role is not defined else omit }}"

    - name: Launch a shell command using the local profile
      ansible.builtin.shell: "env | grep AWS"
      register: output
      environment: "{{ env_vars }}" # => Use the AWS_PROFILE and AWS_REGION set before

    - name: Output with local profile
      debug:
        msg: "{{ output }}"

    - name: Assume a role
      community.aws.sts_assume_role:
        role_arn: "{{ role_to_assume }}"
        role_session_name: "myRoleSessionName"
      changed_when: false
      register: assumed_role
      environment: "{{ env_vars }}" # => Use the AWS_PROFILE and AWS_REGION set before

    - name: Set environment variables; it should only have AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_REGION
      set_fact:
        env_vars:
          AWS_ACCESS_KEY_ID: "{{ assumed_role.sts_creds.access_key if assumed_role is defined else omit }}"
          AWS_SECRET_ACCESS_KEY: "{{ assumed_role.sts_creds.secret_key if assumed_role is defined else omit }}"
          AWS_SESSION_TOKEN: "{{ assumed_role.sts_creds.session_token if assumed_role is defined else omit }}"
          AWS_REGION: "{{ aws_region }}"
          AWS_PROFILE: "{{ aws_profile if assumed_role is not defined else omit }}"

    - name: Launch a shell command using the assumed role
      ansible.builtin.shell: "env | grep AWS"
      register: output
      environment: "{{ env_vars }}" # => Use the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN and AWS_REGION set before

    - name: Output with assumed role
      debug:
        msg: "{{ output }}"

To test, save that ansible playbook yml to a file test.yml

then launch the following command:

YOUR_SOURCE_AWS_PROFILE=""
YOUR_REGION=""
YOUR_ROLE_TO_ASSUME=""

ansible-playbook -i localhost, -e aws_profile=${YOUR_SOURCE_AWS_PROFILE} -e aws_region=${YOUR_REGION} -e role_to_assume=${YOUR_ROLE_TO_ASSUME} test.yml

From there you can your custom Ansible roles and implement the whole solution to get something clean.

Currently I have a role for the assume_role and for serverless deployment, and both of them implement the environment variables flow in order to get flexibility in the multi AWS Account (organization) setup.

The initial setup is done in an inventory, this way the profile, region and role to assume are configured for everybody.