So you have decided to take jump into the devops bandwagon and created Ansible scripts to automate everything. You did everything as per the documents or tutorial, however you run into weird issue with Ansible when you try to run the script to create your brand new ec2 instance.

The full traceback is:
Traceback (most recent call last):
  File "/Users/nitishkumar/.ansible/tmp/ansible-tmp-1597924849.65-271155595794364/", line 102, in 
  File "/Users/nitishkumar/.ansible/tmp/ansible-tmp-1597924849.65-271155595794364/", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/Users/nitishkumar/.ansible/tmp/ansible-tmp-1597924849.65-271155595794364/", line 40, in invoke_module
    runpy.run_module(mod_name='', init_globals=None, run_name='__main__', alter_sys=True)
  File "/usr/local/Cellar/python@2/2.7.17_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 188, in run_module
    fname, loader, pkg_name)
  File "/usr/local/Cellar/python@2/2.7.17_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 82, in _run_module_code
    mod_name, mod_fname, mod_loader, pkg_name)
  File "/usr/local/Cellar/python@2/2.7.17_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 72, in _run_code
    exec code in run_globals
  File "/var/folders/nk/fr7spd0j6m9b7bscgzff4zlh0000gn/T/ansible_ec2_payload_AkLs8v/", line 1721, in 
  File "/var/folders/nk/fr7spd0j6m9b7bscgzff4zlh0000gn/T/ansible_ec2_payload_AkLs8v/", line 1705, in main
  File "/var/folders/nk/fr7spd0j6m9b7bscgzff4zlh0000gn/T/ansible_ec2_payload_AkLs8v/", line 1007, in create_instances
  File "/usr/local/lib/python2.7/site-packages/boto/vpc/", line 1152, in get_all_subnets
    return self.get_list('DescribeSubnets', params, [('item', Subnet)])
  File "/usr/local/lib/python2.7/site-packages/boto/", line 1186, in get_list
    raise self.ResponseError(response.status, response.reason, body)
boto.exception.EC2ResponseError: EC2ResponseError: 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<Message>The subnet ID 'subnet-****' does not exist</Message></Error></Errors><RequestID>074dd297-91db-46dc-a993-0c49a6b32065</RequestID></Response>

No you are not going mad, you are only missing the access key and secret key. While creating the ec2 instance, the client tries to verify that the subnet id and group id does exist. You need to add the access key in your ansible script.

 - name: create ec2 instance 
        # If you do not have a key, check
        key_name: mySecretKey 
        instance_type: t2.micro
        image: "{{ami}}"
        wait: yes
        group_id: "{{ec2_kf_sg.group_id}}"
        region: "{{region}}"
        vpc_subnet_id: default
        assign_public_ip: yes
        aws_access_key: "{{aws_access_key}}"
        aws_secret_key: "{{aws_secret_key}}"  
        vpc_subnet_id: "{{ec2_vpc.subnets.0.subnet_id}}"

What is access key?

Aws requires different types of security credentials depending on how you are trying to access your account. Of course, you would be familiar with username and password which you use to login to aws console, this is a root account access. You can however create numerous additional credentials for your account if you have other people trying to access your account, i.e. employees of your company.

For automated systems or API trying to access your account like aws cli or Ansible, you should ideally create a special user whose credentials would be only used for API access with exact permission which the API needs. This is especially very important if you are using a third party software which needs access to your account, if you use a untrusted software from internet and give it an admin access to your aws account, it could lead to a lot of security issues for you in longer run.

Once you have created a user, you need to get access keys id and secret access key, think of it like username and passwords for API, since API cannot use your regular username and password, they need a sort of special way of authenticating. It is very crucial that you treat these access keys with same kind of security that you do with your root account password.

How to get your access key?

If you want to create a new access key, head over to IAM console in your aws account. Look for users menu and create a new user by clicking Add user. Make sure that you select programmatic access in access type checkbox, this would allow you to generate access key.

Select appropriate permissions in next step, while you can select each of the permission individually to this user, it makes sense to spend some time and create a group for a set of permissions, if you intend to create multiple users for this type.

At the last step, you would be presented with an access key download option. Remember, you get the secret access key, only once when you create the user, if you do not download the keys now, You would never see them again.

How to use access key with Ansible?

Now that you have your access key, you can use them in any api or aws cli. In Ansible there are multiple ways to use the access keys.

The simplest one being adding aws_access_key and aws_secret_key variable in the task

aws_access_key: “{{aws_access_key}}”

aws_secret_key: “{{aws_secret_key}}” 

In this case we are using variables which are defined in an external file liked using include_vars.

Other way is to set these in environment variables, which may be different depending on what operating system you are using.

I spent a few hours trying to break my head over this, hope it helps you save a few moments of agony. If it did help you save your sanity, please do leave a comment.



There are currently no comments.