|
| 1 | +# Ansible AWS Vars Plugin |
| 2 | + |
| 3 | +This is a drop-in plugin for Ansible 2.5+ which provides the following: |
| 4 | + |
| 5 | +* Searches one or more AWS accounts for VPC, subnet, security group and ELB target group details, |
| 6 | +* Matches tags of all these resources with configured set of tag names, then |
| 7 | +* Builds a hierarchical dictionary of resources mapped by tag values, |
| 8 | +* All the above information is made available to all hosts managed by Ansible by means of native host variables |
| 9 | +* Bonus feature: brings native support for multiple AWS accounts with automatic account switching once per playbook based on extra vars passed at runtime. |
| 10 | + |
| 11 | +Read below for more detailed explanations. |
| 12 | + |
| 13 | + |
| 14 | +# How To Use |
| 15 | + |
| 16 | +THis module is shipped with a skeleton structure with the intention that you can test it right out of this repository. However, it's more likely that you already have an Ansible project, in which case all you need to do it copy the `vars_plugins/` directory into your project root (relative to your playbooks). The plugin should be automatically detected by Ansible. |
| 17 | + |
| 18 | +If you have a different vars_plugin directory configured in `ansible.cfg`, just drop `aws.py` and `aws.yml` it into that directory instead. |
| 19 | + |
| 20 | +You'll want to change the settings in `vars_plugin/aws.yml` to match your environment. These settings are: |
| 21 | + |
| 22 | +`regions:` |
| 23 | +This is a list of regions where the plugin will look for resources |
| 24 | + |
| 25 | +`use_cache: [yes|no]` |
| 26 | +Whether or not to cache resource details after retrieving them. Recommended. |
| 27 | + |
| 28 | +`cache_max_age: 600` |
| 29 | +How long to cache resource details before retrieving them again from AWS. Defaults to 600 seconds (10 mins). |
| 30 | + |
| 31 | +`cache_env_vars:` |
| 32 | +A list of environment variables to inspect and save the values of when caching resource details. Should the values of any of these environment variables change, the cache will be invalidated. |
| 33 | + |
| 34 | +`aws_profiles:` |
| 35 | +Can be either a list of profile names, or a dictionary having profile names as keys, and each value being a dictionary of extra variables to inspect when selecting a default account for the current playbook (see below). When a list, no matching is performed and no credentials are set. |
| 36 | + |
| 37 | +`vpc_tags:` |
| 38 | +A list of tag keys to match when building a dictionary of VPC IDs. When specified, the global host variable `vpc_ids` contains a nested dictionary of resource IDs denominated by tag values. If not specified, no dictonary is set. |
| 39 | + |
| 40 | +`subnet_tags:` |
| 41 | +A list of tag keys to match when building a dictionary of subnet IDs. When specified, the global host variable `subnet_ids` contains a nested dictionary of resource IDs denominated by tag values. If not specified, no dictonary is set. |
| 42 | + |
| 43 | +`security_group_tags:` |
| 44 | +A list of tag keys to match when building a dictionary of security group IDs. When specified, the global host variable `security_group_ids` contains a nested dictionary of resource IDs denominated by tag values. If not specified, no dictonary is set. |
| 45 | + |
| 46 | +`elb_target_group_tags:` |
| 47 | +A list of tag keys to match when building a dictionary of ELB target groups IDs. When specified, the global host variable `elb_target_group_ids` contains a nested dictionary of resource IDs denominated by tag values. If not specified, no dictonary is set. |
| 48 | + |
| 49 | + |
| 50 | +# AWS Resources |
| 51 | + |
| 52 | +In the configuration file for this plugin, you can specify a list of tag keys for each type of supported resource. When the plugin runs (right before playbook execution) it fetches resource descriptions from AWS and organizes them into hierarchical dictionaries based on the values of the configured tag keys. |
| 53 | + |
| 54 | +For example, given this configuration: |
| 55 | + |
| 56 | +```yaml |
| 57 | +subnet_tags: |
| 58 | + - project |
| 59 | + - env |
| 60 | + - tier |
| 61 | +``` |
| 62 | +
|
| 63 | +and having subnets in your AWS account(s) like: |
| 64 | +
|
| 65 | +Subnet ID | Tag: project | Tag: env | Tag: tier |
| 66 | +--------------- | ------------ | -------- | --------- |
| 67 | +subnet-aabbcc12 | apollo | prod | app |
| 68 | +subnet-aabbcc13 | apollo | prod | app |
| 69 | +subnet-aabbcc14 | apollo | prod | data |
| 70 | +subnet-aabbcc15 | apollo | prod | data |
| 71 | +subnet-aabbcc16 | apollo | prod | lb |
| 72 | +subnet-aabbcc17 | apollo | prod | lb |
| 73 | +subnet-aabbcc18 | apollo | stage | app |
| 74 | +subnet-aabbcc19 | apollo | stage | app |
| 75 | +subnet-aabbcc20 | apollo | stage | data |
| 76 | +subnet-aabbcc21 | apollo | stage | data |
| 77 | +subnet-aabbcc22 | apollo | stage | lb |
| 78 | +subnet-aabbcc23 | apollo | stage | lb |
| 79 | +subnet-aabbcc24 | manhattan | prod | app |
| 80 | +subnet-aabbcc25 | manhattan | prod | app |
| 81 | +subnet-aabbcc26 | manhattan | prod | data |
| 82 | +subnet-aabbcc27 | manhattan | prod | data |
| 83 | +subnet-aabbcc28 | manhattan | prod | lb |
| 84 | +subnet-aabbcc29 | manhattan | prod | lb |
| 85 | +subnet-aabbcc30 | manhattan | stage | app |
| 86 | +subnet-aabbcc31 | manhattan | stage | app |
| 87 | +subnet-aabbcc32 | manhattan | stage | data |
| 88 | +subnet-aabbcc33 | manhattan | stage | data |
| 89 | +subnet-aabbcc34 | manhattan | stage | lb |
| 90 | +subnet-aabbcc35 | manhattan | stage | lb |
| 91 | +
|
| 92 | +You'll end up with a global dictionary like: |
| 93 | +
|
| 94 | +```yaml |
| 95 | +subnet_ids: |
| 96 | + us-east-1: |
| 97 | + apollo: |
| 98 | + prod: |
| 99 | + app: |
| 100 | + - subnet-aabbcc12 |
| 101 | + - subnet-aabbcc13 |
| 102 | + data: |
| 103 | + - subnet-aabbcc14 |
| 104 | + - subnet-aabbcc15 |
| 105 | + lb: |
| 106 | + - subnet-aabbcc16 |
| 107 | + - subnet-aabbcc17 |
| 108 | + stage: |
| 109 | + app: |
| 110 | + - subnet-aabbcc18 |
| 111 | + - subnet-aabbcc19 |
| 112 | + data: |
| 113 | + - subnet-aabbcc20 |
| 114 | + - subnet-aabbcc21 |
| 115 | + lb: |
| 116 | + - subnet-aabbcc22 |
| 117 | + - subnet-aabbcc23 |
| 118 | + manhattan: |
| 119 | + prod: |
| 120 | + app: |
| 121 | + - subnet-aabbcc24 |
| 122 | + - subnet-aabbcc25 |
| 123 | + data: |
| 124 | + - subnet-aabbcc26 |
| 125 | + - subnet-aabbcc27 |
| 126 | + lb: |
| 127 | + - subnet-aabbcc28 |
| 128 | + - subnet-aabbcc29 |
| 129 | + stage: |
| 130 | + app: |
| 131 | + - subnet-aabbcc30 |
| 132 | + - subnet-aabbcc31 |
| 133 | + data: |
| 134 | + - subnet-aabbcc32 |
| 135 | + - subnet-aabbcc33 |
| 136 | + lb: |
| 137 | + - subnet-aabbcc34 |
| 138 | + - subnet-aabbcc35 |
| 139 | +``` |
| 140 | +
|
| 141 | +The same pattern is implemented for VPCs, subnets, security groups and ELB target groups, alowing you to specify and target resources in your playbooks without hard coding resource IDs, without using `*_facts` modules everywhere, and without needing to know the exact names of every resource. It's important to note that these resources can reside in any number of AWS accounts, as long as they can be reached by your Ansible control host. |
| 142 | + |
| 143 | + |
| 144 | +# Multi Account Support |
| 145 | + |
| 146 | +The multi account support provided by this plugin comes in two flavors. |
| 147 | + |
| 148 | +1. With multiple accounts configured as AWS profiles on your Ansible control host, the plugin will traverse all accounts to retrieve resource information. |
| 149 | +2. Additionally, with rules configured in the configuration file, it will inspect any extra vars you specify when running your playbook and *automatically select* one of the profiles to use for your playbook execution. This is accomplished by requesting temporary credentials from STS and exporting them within Ansible as a set of `AWS_*` environment variables. These exported env vars are consumed by Boto2 and Boto3-based modules alike. |
| 150 | + |
| 151 | +The primary limitation of this approach is that the AWS account is selected once, prior to playbook execution. However, it's possible to trivially use a different account for a given task by requesting credentials with the `sts_assume_role` module and specifying them explicitly for a task, which overrides the environment variables set by this plugin. |
| 152 | + |
| 153 | +# Regions |
| 154 | + |
| 155 | +For maximum control, this plugin requires that regions be explicitly configured. The configuration setting `regions` is a list. All regions configured will be searched for resources, and the resulting dictionaries are nested by region. |
| 156 | + |
| 157 | +# Resource Caching |
| 158 | + |
| 159 | +Just like Ansible's EC2 inventory script, this plugin caches all the resource information it finds, in order to speed up subsequent playbook executions. The cache can be disabled by setting `use_cache: no` in the configuration file, and the cache timeout (which defaults to 10 minutes) can be specified [in seconds] with the `cache_max_age` setting. |
| 160 | + |
| 161 | +It's possible that factors outside of Ansible could invalidate cached information, so it's also possible to configure one or more environment variables, the values of which will be saved and if they change between playbok runs, the cache will be automatically invalidated. |
| 162 | + |
0 commit comments