You’re a (prospective) contributor to Ansible, and you have some great improvements to make to an existing module or a brand new module. As a conscientious developer, you know that having tests will ensure that you don’t break existing behaviour, and that other people’s future enhancements won’t break your desired behaviour. The standard tests for AWS modules are integration tests as most of them rely on creating some resources in AWS, updating them, and then cleaning up afterwards.
I’ll start this post from absolute first principles—I’ll use a shiny new Fedora 26 vagrant VM.
Setting up Ansible for development
vagrant init fedora/26-cloud-base
vagrant up
vagrant ssh
The easiest way to ensure we have all the dependencies for Ansible
installed is then to use dnf
to install ansible.
sudo dnf install ansible
Next, clone the your fork of the source code for ansible:
ssh-keygen
eval `ssh-agent -s`
ssh-add
# Add the generated key to your github account
sudo dnf install git
git clone git@github.com:YOURUSER/ansible
cd ansible
git remote add upstream https://github.com/ansible/ansible
git pull upstream devel
Note that if you’re doing this on a host with any other ssh keys,
it’s worth generating a github specific ssh key (using e.g.
ssh-keygen -f ~/.ssh/github
) and setting up
your .ssh/config appropriately:
Host github.com
IdentityFile ~/.ssh/github
At this point, ansible --version
should give the released version of
Ansible (at the time of writing, this was 2.3.1.0). To use the development
version (not recommended for production use), do:
source hacking/env-setup
And ansible --version
should now show the development version (currently
2.4.0)
Install docker
Add docker and set it up so that you don’t have to be root to run it. There are some security implications with this—being in the docker group is effectively equivalent to root access.
sudo dnf install docker
sudo groupadd docker
sudo gpasswd -a $USER docker
sudo systemctl restart docker
newgrp docker
Setting up AWS account
Install the relevant command line tools (you can do this in a virtualenv if you prefer—it depends if you’d need to test with different versions of boto3 etc). The boto library is currently still required for quite a few modules, as well as the common code used to connect to AWS.
pip install --user botocore boto3 boto awscli
Ensure you have an IAM administrative user with API access. DO NOT use this user for Ansible, or put its credentials anywhere near your git repo! I use boto profiles for all of the AWS accounts that I use, and don’t have a default profile so that I always have to choose.
Note: DO NOT use your AWS root user—if you don’t have a suitable user yet, create a new IAM user with the AdministratorAccess managed policy (or similar) attached
Ensure a profile for this IAM user exists in ~/.aws/credentials and then run:
export ADMIN_PROFILE=$your_profile_name
ansible-playbook hacking/aws_config/setup-iam.yml -e iam_group=ansible_test -e profile=$ADMIN_PROFILE -e region=us-east-2 -vv
You don’t actually have to set profile or region at all if you don’t need
them—region defaults to us-east-1
, but you can only choose us-east-2
as an alternative at this time.
You’ll now need to go into AWS console, create an IAM user (called e.g. ansible_test
)
and make them a member of
the newly created group (ansible_test
if you used that with iam_group
in
While you’re there, create an API credential for the test user.
This can all be automated:
aws iam create-user --user-name ansible_test --profile $ADMIN_PROFILE
aws iam add-user-to-group --user-name ansible_test --group_name ansible_test --profile $ADMIN_PROFILE
aws iam create-access-key --user-name ansible_test --profile $ADMIN_PROFILE
Note: This can be done through Ansible’s iam module
too. It’s just simpler to document the steps with the CLI as they fit on three lines
rather than one very long ansible
adhoc command line or a larger ansible playbook.
Using the information from the new credential, you can do:
cp test/integration/cloud-config-aws.yml.template test/integration/cloud-config-aws.yml
and then update that file to include this new secret key and access key.
It’s also worth adding the following for region
if you’re not using us-east-1
aws_region: us-east-2
ec2_region: "{{ aws_region }}"
Note: The credentials in ~/.aws/credentials and cloud-config-aws.yml should be completely different. A good way to test this is:
aws sts get-caller-identity --profile=$ADMIN_PROFILE
ansible -m shell -a 'AWS_SECRET_ACCESS_KEY={{ aws_secret_key }} AWS_ACCESS_KEY_ID={{ aws_access_key }} aws sts get-caller-identity' \
-e @test/integration/cloud-config-aws.yml localhost
The first of these should return your administrator user. The second of these should return your Ansible test user. If this isn’t the case, check the previous steps (and let me know if I can improve the documentation!).
Ensuring your user has the correct IAM policies
ansible-playbook hacking/aws_config/setup-iam.yml -e region=us-east-2 \
-e profile=$ADMIN_PROFILE -e iam_group=ansible_test -vv
If you need additional IAM policies for your module, you’ll need to add these
to a new or an existing policy file in hacking/aws_config/testing_policies
.
Note that there is a maximum of 10 policies per group, so we’re now using consolidated
policies (e.g. compute, storage, network) etc. rather than a policy per service.
Adding the necessary policies here is a good way of documenting the new policies that you need, which will also help Ansible’s AWS account administrators add the policies needed by the CI account.
Running an integration test suite
Check that you can run the integration tests
ansible-test integration --docker -v ec2_group
The first run will be quite slow as you need to pull down all the required containers.
Future runs will be much quicker, particularly if you pass --docker-no-pull
to
speed things up (it’s worth updating the containers fairly regularly, of course)
Writing your own tests
For your module, you will need:
test/integration/module_name/aliases
test/integration/module_name/tasks/main.yml