Ansible Role - awscliv2

Rob MitchellRob Mitchell
3 min read

I have a number of AWS EC2 instances that interact with other AWS services on a regular basis. These instances so things like sending files to AWS S3 or sending email via AWS SES. One way to interact with AWS services from the virtual machine level is to have the awscli installed. In this post we will create an Ansible role that installs and configures the awscli version 2.

TLDR: Role is on github.com

This role's directory structure is quite simple. From your roles directory simply make the awscliv2 directory along with the vars and tasks sub-directories.

$ mkdir -p roles/awscliv2/{vars,tasks}
$ tree roles/awscliv2/
roles/awscliv2/
├── tasks
└── vars

2 directories, 0 files
$

To run commands with the AWS cli you need to know the region you want to use as well as a aws_access_key_id and a aws_secret_access_key. You can get these value in your account on the AWS console. Let's start our role by making these variables for the role in the vars directory. Obviously replace the X values with your own.

$ cat roles/awscliv2/vars/main.yml 
---
AWSCLI_AWS_ACCESS_KEY_ID: XXXXX
AWSCLI_AWS_SECRET_ACCESS_KEY: XXXXX
AWSCLI_AWS_REGION: us-east-1
$

Now we have the variables that the playbook will use, we need a playbook. A playbook is a simple YAML file that allow Ansible to create and/or enforce repeatable, reusable configuration. We will build this playbook one "play" or task at a time starting with downloading the awscli version 2 from AWS. The playbook assumes curl is installed.

 $ cat roles/awscliv2/tasks/main.yml 
---
- name: download awscliv2 from aws
  ansible.builtin.shell:
    cmd: "curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /var/tmp/awscliv2.zip"
    creates: /var/tmp/awscliv2.zip
$

The task is as simple as it reads: download a zip file from AWS using the shell and curl command to the /var/tmp directory. The tasks looks for /var/tmp/awscliv2.zip and if it already exists does not download it again.

Next we need to unzip the awscliv2.zip file so lets add that task to the playbook. Again we use the shell and assume unzip is installed.

- name: unzip /var/tmp/awscliv2.zip
  ansible.builtin.shell:
    cmd: "unzip awscliv2.zip"
    chdir: /var/tmp
    creates: /var/tmp/aws/install

The task unzips the zip file. Each time the task is applied Ansible looks for the /var/tmp/aws/install file and if it already exists does not unzip the zip file again.

Now that we have the extracted installation files, the next task is to do the install.

- name: install awscli v2
  ansible.builtin.shell:
    cmd: ./aws/install 
    chdir: /var/tmp
    creates: /usr/local/bin/aws

Again with the "creates" creates parameter, Ansible won't run the install script if /usr/local/bin/aws exists.

With the installation completed the rest of the tasks create/enforce the configuration. Starting with the .aws config directory.

- name: awscli config directory
  file:
    state: directory
    path: "~{{ ansible_user }}/.aws"
    owner: "{{ ansible_user }}"
    group: "{{ ansible_user }}"
    mode: '0700'

Now that Ansible has made the directory the next two tasks add the 'config' and 'credentials' files. Both configuration files use the variables we created in vars/main.yml.

- name: awscli config file
  copy:
    dest: "~{{ ansible_user }}/.aws/config"
    owner: "{{ ansible_user }}"
    group: "{{ ansible_user }}"
    mode: '0600'
    content: |
      [default]
      region = {{ AWSCLI_AWS_REGION }}
- name: awscli credentials file
  copy:
    dest: "~{{ ansible_user }}/.aws/credentials"
    owner: "{{ ansible_user }}"
    group: "{{ ansible_user }}"
    mode: '0600'
    content: |
      [default]
      aws_access_key_id = {{ AWSCLI_AWS_ACCESS_KEY_ID }}
      aws_secret_access_key = {{ AWSCLI_AWS_SECRET_ACCESS_KEY }}

And now you have an Ansible role for installing and configuring the awscli version 2. You can clone it from github.com

To verify, simply logon to a targeted host and run the awscli command:

$ /usr/local/bin/aws --version 
aws-cli/2.7.13 Python/3.9.11 Linux/5.4.0-186-generic exe/x86_64.ubuntu.20 prompt/off
$
# "whoami":
$ /usr/local/bin/aws sts  get-caller-identity

References, etc:

0
Subscribe to my newsletter

Read articles from Rob Mitchell directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rob Mitchell
Rob Mitchell