ec2_snapshot 5.65 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#!/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 <http://www.gnu.org/licenses/>.

DOCUMENTATION = '''
---
module: ec2_snapshot
short_description: creates a snapshot from an existing volume
description:
    - creates an EC2 snapshot from an existing EBS volume
version_added: "1.5"
options:
  region:
    description:
      - The AWS region to use. If not specified then the value of the EC2_REGION environment variable, if any, is used.
    required: false
    default: null
    aliases: ['aws_region', 'ec2_region']
  volume_id:
    description:
      - volume from which to take the snapshot
    required: false
    default: null
    aliases: []
  description:
    description:
      - description to be applied to the snapshot
    required: false
    default: null
    aliases: []
  instance_id:
44
    description:
follower committed
45
    - instance that has the required volume to snapshot mounted
46 47 48 49
    required: false
    default: null
    aliases: []
  device_name:
50
    description:
51 52 53 54
    - device name of a mounted volume to be snapshotted
    required: false
    default: null
    aliases: []
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
  profile:
    description:
      - uses a boto profile. Only works with boto >= 2.24.0
    required: false
    default: null
    aliases: []
    version_added: "1.6"
  security_token:
    description:
      - security token to authenticate against AWS
    required: false
    default: null
    aliases: []
    version_added: "1.6"
  snapshot_tags:
    description:
Atlas Health committed
71
      - a hash/dictionary of tags to add to the snapshot
72 73 74 75
    required: false
    default: null
    aliases: []
    version_added: "1.6"
76

77
author: Will Thames
78
extends_documentation_fragment: aws
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
'''

EXAMPLES = '''
# Simple snapshot of volume using volume_id
- local_action: 
    module: ec2_snapshot 
    volume_id: vol-abcdef12   
    description: snapshot of /data from DB123 taken 2013/11/28 12:18:32

# Snapshot of volume mounted on device_name attached to instance_id
- local_action: 
    module: ec2_snapshot 
    instance_id: i-12345678
    device_name: /dev/sdb1
    description: snapshot of /data from DB123 taken 2013/11/28 12:18:32
Atlas Health committed
94 95 96 97 98 99 100 101 102

# Snapshot of volume with tagging
- local_action: 
    module: ec2_snapshot 
    instance_id: i-12345678
    device_name: /dev/sdb1
    snapshot_tags:
        frequency: hourly
        source: /data
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
'''    

import sys
import time

try:
    import boto.ec2
except ImportError:
    print "failed=True msg='boto required for this module'"
    sys.exit(1)

def main():
    module = AnsibleModule(
        argument_spec = dict(
            volume_id = dict(),
            description = dict(),
            instance_id = dict(),
            device_name = dict(),
            region = dict(aliases=['aws_region', 'ec2_region'], choices=AWS_REGIONS),
            ec2_url = dict(),
            ec2_secret_key = dict(aliases=['aws_secret_key', 'secret_key'], no_log=True),
            ec2_access_key = dict(aliases=['aws_access_key', 'access_key']),
125
            wait = dict(type='bool', default='true'),
126
            wait_timeout = dict(default=0),
127
            snapshot_tags = dict(type='dict', default=dict()),
128 129 130 131 132 133 134
        )
    )

    volume_id = module.params.get('volume_id')
    description = module.params.get('description')
    instance_id = module.params.get('instance_id')
    device_name = module.params.get('device_name')
135
    wait = module.params.get('wait')
Hagai committed
136
    wait_timeout = module.params.get('wait_timeout')
137
    snapshot_tags = module.params.get('snapshot_tags')
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156

    if not volume_id and not instance_id or volume_id and instance_id:
        module.fail_json('One and only one of volume_id or instance_id must be specified')
    if instance_id and not device_name or device_name and not instance_id:
        module.fail_json('Instance ID and device name must both be specified')

    ec2 = ec2_connect(module)

    if instance_id:
        try:
            volumes = ec2.get_all_volumes(filters={'attachment.instance-id': instance_id, 'attachment.device': device_name})
            if not volumes:
                module.fail_json(msg="Could not find volume with name %s attached to instance %s" % (device_name, instance_id))
            volume_id = volumes[0].id
        except boto.exception.BotoServerError, e:
            module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))

    try:
        snapshot = ec2.create_snapshot(volume_id, description=description)
Hagai committed
157
        time_waited = 0
158 159 160 161 162
        if wait:
            snapshot.update()
            while snapshot.status != 'completed':
                time.sleep(3)
                snapshot.update()
Hagai committed
163 164 165
                time_waited += 3
                if wait_timeout and time_waited > wait_timeout:
                    module.fail_json('Timed out while creating snapshot.')
166 167
        for k, v in snapshot_tags.items():
            snapshot.add_tag(k, v)
168 169 170
    except boto.exception.BotoServerError, e:
        module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))

171 172
    module.exit_json(changed=True, snapshot_id=snapshot.id, volume_id=snapshot.volume_id,
            volume_size=snapshot.volume_size, tags=snapshot.tags.copy())
173 174 175 176 177 178

# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.ec2 import *

main()