#!/usr/bin/python # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . DOCUMENTATION = ''' --- module: ec2_tag short_description: create and remove tag(s) to ec2 resources. description: - Creates, removes and lists tags from any EC2 resource. The resource is referenced by its resource id (e.g. an instance being i-XXXXXXX). It is designed to be used with complex args (tags), see the examples. This module has a dependency on python-boto. version_added: "1.3" options: resource: description: - The EC2 resource id. required: true default: null aliases: [] state: description: - Whether the tags should be present or absent on the resource. Use list to interrogate the tags of an instance. required: false default: present choices: ['present', 'absent', 'list'] aliases: [] region: description: - region in which the resource exists. required: false default: null aliases: ['aws_region', 'ec2_region'] author: Lester Wade extends_documentation_fragment: aws ''' EXAMPLES = ''' # Basic example of adding tag(s) tasks: - name: tag a resource local_action: ec2_tag resource=vol-XXXXXX region=eu-west-1 state=present args: tags: Name: ubervol env: prod # Playbook example of adding tag(s) to spawned instances tasks: - name: launch some instances local_action: ec2 keypair={{ keypair }} group={{ security_group }} instance_type={{ instance_type }} image={{ image_id }} wait=true region=eu-west-1 register: ec2 - name: tag my launched instances local_action: ec2_tag resource={{ item.id }} region=eu-west-1 state=present with_items: ec2.instances args: tags: Name: webserver env: prod ''' # Note: this module needs to be made idempotent. Possible solution is to use resource tags with the volumes. # if state=present and it doesn't exist, create, tag and attach. # Check for state by looking for volume attachment with tag (and against block device mapping?). # Would personally like to revisit this in May when Eucalyptus also has tagging support (3.3). import sys import time try: import boto.ec2 except ImportError: print "failed=True msg='boto required for this module'" sys.exit(1) def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict( resource = dict(required=True), tags = dict(), state = dict(default='present', choices=['present', 'absent', 'list']), ) ) module = AnsibleModule(argument_spec=argument_spec) resource = module.params.get('resource') tags = module.params.get('tags') state = module.params.get('state') ec2 = ec2_connect(module) # We need a comparison here so that we can accurately report back changed status. # Need to expand the gettags return format and compare with "tags" and then tag or detag as appropriate. filters = {'resource-id' : resource} gettags = ec2.get_all_tags(filters=filters) dictadd = {} dictremove = {} baddict = {} tagdict = {} for tag in gettags: tagdict[tag.name] = tag.value if state == 'present': if not tags: module.fail_json(msg="tags argument is required when state is present") if set(tags.items()).issubset(set(tagdict.items())): module.exit_json(msg="Tags already exists in %s." %resource, changed=False) else: for (key, value) in set(tags.items()): if (key, value) not in set(tagdict.items()): dictadd[key] = value tagger = ec2.create_tags(resource, dictadd) gettags = ec2.get_all_tags(filters=filters) module.exit_json(msg="Tags %s created for resource %s." % (dictadd,resource), changed=True) if state == 'absent': if not tags: module.fail_json(msg="tags argument is required when state is absent") for (key, value) in set(tags.items()): if (key, value) not in set(tagdict.items()): baddict[key] = value if set(baddict) == set(tags): module.exit_json(msg="Nothing to remove here. Move along.", changed=False) for (key, value) in set(tags.items()): if (key, value) in set(tagdict.items()): dictremove[key] = value tagger = ec2.delete_tags(resource, dictremove) gettags = ec2.get_all_tags(filters=filters) module.exit_json(msg="Tags %s removed for resource %s." % (dictremove,resource), changed=True) if state == 'list': module.exit_json(changed=False, tags=tagdict) sys.exit(0) # import module snippets from ansible.module_utils.basic import * from ansible.module_utils.ec2 import * main()