def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(state=dict(required=True, choices=['present', 'absent']), id_to_associate=dict( required=True, aliases=['link_aggregation_group_id', 'connection_id']), public=dict(type='bool'), name=dict(), vlan=dict(type='int', default=100), bgp_asn=dict(type='int', default=65000), authentication_key=dict(), amazon_address=dict(), customer_address=dict(), address_type=dict(), cidr=dict(type='list'), virtual_gateway_id=dict(), virtual_interface_id=dict())) module = AnsibleAWSModule( argument_spec=argument_spec, required_one_of=[['virtual_interface_id', 'name']], required_if=[['state', 'present', ['public']], ['public', False, ['virtual_gateway_id']], ['public', True, ['amazon_address']], ['public', True, ['customer_address']], ['public', True, ['cidr']]]) region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True) connection = boto3_conn(module, conn_type='client', resource='directconnect', region=region, endpoint=ec2_url, **aws_connect_kwargs) try: changed, latest_state = ensure_state(connection, module) except DirectConnectError as e: if e.exception: module.fail_json_aws(exception=e.exception, msg=e.msg) else: module.fail_json(msg=e.msg) module.exit_json(changed=changed, **camel_dict_to_snake_dict(latest_state))
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( deregister_unused=dict(type='bool', default=False), target_az=dict(type='str'), target_group_arn=dict(type='str'), target_group_name=dict(type='str'), target_id=dict(type='str', required=True), target_port=dict(type='int'), target_status=dict(choices=[ 'initial', 'healthy', 'unhealthy', 'unused', 'draining', 'unavailable' ], type='str'), target_status_timeout=dict(type='int', default=60), state=dict(required=True, choices=['present', 'absent'], type='str'), )) module = AnsibleModule( argument_spec=argument_spec, mutually_exclusive=[['target_group_arn', 'target_group_name']]) if not HAS_BOTO3: module.fail_json(msg='boto3 required for this module') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) connection = boto3_conn(module, conn_type='client', resource='elbv2', region=region, endpoint=ec2_url, **aws_connect_params) state = module.params.get("state") if state == 'present': register_target(connection, module) else: deregister_target(connection, module)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(name=dict(type='str'), state=dict(default='present', choices=['present', 'absent']), strategy=dict(default='cluster', choices=['cluster', 'spread']))) module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) connection = boto3_conn(module, resource='ec2', conn_type='client', region=region, endpoint=ec2_url, **aws_connect_params) state = module.params.get("state") if state == 'present': placement_group = get_placement_group_details(connection, module) if placement_group is None: create_placement_group(connection, module) else: strategy = module.params.get("strategy") if placement_group['strategy'] == strategy: module.exit_json(changed=False, placement_group=placement_group) else: name = module.params.get("name") module.fail_json( msg=("Placement group '{}' exists, can't change strategy" + " from '{}' to '{}'" ).format(name, placement_group['strategy'], strategy)) elif state == 'absent': placement_group = get_placement_group_details(connection, module) if placement_group is None: module.exit_json(changed=False) else: delete_placement_group(connection, module)
def dependencies(): # each LAG dict will contain the keys: module, connections, virtual_interfaces Dependencies = collections.namedtuple("Dependencies", ["lag_1", "lag_2"]) lag_1 = dict() lag_2 = dict() vanilla_params = {"name": "ansible_lag_1", "location": "EqSe2", "num_connections": 1, "min_links": 0, "bandwidth": "1Gbps"} for lag in ("ansible_lag_1", "ansible_lag_2"): params = dict(vanilla_params) params["name"] = lag if lag == "ansible_lag_1": lag_1["module"] = FakeModule(**params) else: lag_2["module"] = FakeModule(**params) if os.getenv("PLACEBO_RECORD"): region, ec2_url, aws_connect_kwargs = get_aws_connection_info(lag_1["module"], boto3=True) client = boto3_conn(lag_1["module"], conn_type="client", resource="directconnect", region=region, endpoint=ec2_url, **aws_connect_kwargs) # See if link aggregation groups exist for name in ("ansible_lag_1", "ansible_lag_2"): lag_id = lag_module.create_lag(client, num_connections=1, location="EqSe2", bandwidth="1Gbps", name=name, connection_id=None) if name == "ansible_lag_1": lag_1["lag_id"] = lag_id lag_1["name"] = name else: lag_2["lag_id"] = lag_id lag_2["name"] = name yield Dependencies(lag_1=lag_1, lag_2=lag_2) else: lag_1.update(lag_id="dxlag-fgkk4dja", name="ansible_lag_1") lag_2.update(lag_id="dxlag-fgytkicv", name="ansible_lag_2") yield Dependencies(lag_1=lag_1, lag_2=lag_2) if os.getenv("PLACEBO_RECORD"): # clean up lag_module.ensure_absent(client, lag_1["lag_id"], lag_1["name"], True, True, True, 120) lag_module.ensure_absent(client, lag_2["lag_id"], lag_2["name"], True, True, True, 120)
def __init__(self, module, cluster, ec2_id): self.module = module self.cluster = cluster self.ec2_id = ec2_id region, ec2_url, aws_connect_kwargs = get_aws_connection_info( module, boto3=True) if not region: module.fail_json(msg=("Region must be specified as a parameter," " in EC2_REGION or AWS_REGION environment" " variables or in boto configuration file")) self.ecs = boto3_conn(module, conn_type='client', resource='ecs', region=region, endpoint=ec2_url, **aws_connect_kwargs) self.ecs_arn = self._get_ecs_arn()
def __init__(self, module): self.module = module try: region, ec2_url, aws_connect_kwargs = get_aws_connection_info( module, boto3=True) if not region: module.fail_json( msg= "Region must be specified as a parameter, in EC2_REGION or AWS_REGION environment variables or in boto configuration file" ) self.ec2 = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_kwargs) except ClientError as e: module.fail_json(msg=e.message)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( name=dict(required=False, default=[], type='list'), sort=dict(required=False, default=None, choices=[ 'launch_configuration_name', 'image_id', 'created_time', 'instance_type', 'kernel_id', 'ramdisk_id', 'key_name' ]), sort_order=dict(required=False, default='ascending', choices=['ascending', 'descending']), sort_start=dict(required=False, type='int'), sort_end=dict(required=False, type='int'), )) module = AnsibleModule(argument_spec=argument_spec) if module._name == 'ec2_lc_facts': module.deprecate( "The 'ec2_lc_facts' module has been renamed to 'ec2_lc_info'", version='2.13') if not HAS_BOTO3: module.fail_json(msg='boto3 required for this module') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) if region: connection = boto3_conn(module, conn_type='client', resource='autoscaling', region=region, endpoint=ec2_url, **aws_connect_params) else: module.fail_json(msg="region must be specified") list_launch_configs(connection, module)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( query=dict(choices=['services', 'endpoints'], required=True), filters=dict(default={}, type='dict'), vpc_endpoint_ids=dict(type='list'), )) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if module._name == 'ec2_vpc_endpoint_facts': module.deprecate( "The 'ec2_vpc_endpoint_facts' module has been renamed to 'ec2_vpc_endpoint_info'", version='2.13') # Validate Requirements if not HAS_BOTO3: module.fail_json(msg='botocore and boto3 are required.') try: region, ec2_url, aws_connect_params = get_aws_connection_info( module, boto3=True) if region: connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params) else: module.fail_json(msg="region must be specified") except botocore.exceptions.NoCredentialsError as e: module.fail_json(msg=str(e)) invocations = { 'services': get_supported_services, 'endpoints': get_endpoints, } results = invocations[module.params.get('query')](connection, module) module.exit_json(**results)
def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict(filters=dict(default={}, type='dict'))) module = AnsibleModule(argument_spec=argument_spec) if module._name == 'aws_region_facts': module.deprecate( "The 'aws_region_facts' module has been renamed to 'aws_region_info'", version='2.13') if not HAS_BOTO3: module.fail_json(msg='boto3 required for this module') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params) # Replace filter key underscores with dashes, for compatibility sanitized_filters = dict((k.replace('_', '-'), v) for k, v in module.params.get('filters').items()) try: regions = connection.describe_regions( Filters=ansible_dict_to_boto3_filter_list(sanitized_filters)) except ClientError as e: module.fail_json(msg="Unable to describe regions: {0}".format( to_native(e)), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) except BotoCoreError as e: module.fail_json(msg="Unable to describe regions: {0}".format( to_native(e)), exception=traceback.format_exc()) module.exit_json( regions=[camel_dict_to_snake_dict(r) for r in regions['Regions']])
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(autoscaling_group_name=dict(required=True, type='str'), lifecycle_hook_name=dict(required=True, type='str'), transition=dict(type='str', choices=[ 'autoscaling:EC2_INSTANCE_TERMINATING', 'autoscaling:EC2_INSTANCE_LAUNCHING' ]), role_arn=dict(type='str'), notification_target_arn=dict(type='str'), notification_meta_data=dict(type='str'), heartbeat_timeout=dict(type='int'), default_result=dict(default='ABANDON', choices=['ABANDON', 'CONTINUE']), state=dict(default='present', choices=['present', 'absent']))) module = AnsibleAWSModule( argument_spec=argument_spec, required_if=[['state', 'present', ['transition']]]) state = module.params.get('state') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) connection = boto3_conn(module, conn_type='client', resource='autoscaling', region=region, endpoint=ec2_url, **aws_connect_params) changed = False if state == 'present': changed = create_lifecycle_hook(connection, module) elif state == 'absent': changed = delete_lifecycle_hook(connection, module) module.exit_json(changed=changed)
def main(): """ Get list of S3 buckets :return: """ # Ensure we have an empty dict result = {} # Including ec2 argument spec module = AnsibleModule(argument_spec=ec2_argument_spec(), supports_check_mode=True) is_old_facts = module._name == 'aws_s3_bucket_facts' if is_old_facts: module.deprecate( "The 'aws_s3_bucket_facts' module has been renamed to 'aws_s3_bucket_info', " "and the renamed one no longer returns ansible_facts", version='2.13') # Verify Boto3 is used if not HAS_BOTO3: module.fail_json(msg='boto3 required for this module') # Set up connection region, ec2_url, aws_connect_params = get_aws_connection_info( module, boto3=HAS_BOTO3) connection = boto3_conn(module, conn_type='client', resource='s3', region=region, endpoint=ec2_url, **aws_connect_params) # Gather results result['buckets'] = get_bucket_list(module, connection) # Send exit if is_old_facts: module.exit_json(msg="Retrieved s3 facts.", ansible_facts=result) else: module.exit_json(msg="Retrieved s3 info.", **result)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( name_regex=dict(required=True), sort_order=dict(required=False, default='ascending', choices=['ascending', 'descending']), limit=dict(required=False, type='int'), )) module = AnsibleModule(argument_spec=argument_spec, ) region, ec2_url, aws_connect_params = get_aws_connection_info(module, True) client = boto3_conn(module=module, conn_type='client', resource='autoscaling', region=region, **aws_connect_params) find_launch_configs(client, module)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( domain_name=dict(aliases=['name']), statuses=dict(type='list', choices=['PENDING_VALIDATION', 'ISSUED', 'INACTIVE', 'EXPIRED', 'VALIDATION_TIMED_OUT', 'REVOKED', 'FAILED']), ) ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if module._name == 'aws_acm_facts': module.deprecate("The 'aws_acm_facts' module has been renamed to 'aws_acm_info'", version='2.13') if not HAS_BOTO3: module.fail_json(msg='boto3 and botocore are required by this module') region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True) client = boto3_conn(module, conn_type='client', resource='acm', region=region, endpoint=ec2_url, **aws_connect_kwargs) certificates = get_certificates(client, module, domain_name=module.params['domain_name'], statuses=module.params['statuses']) module.exit_json(certificates=certificates)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( customer_gateway_ids=dict(default=[], type='list'), filters=dict(default={}, type='dict') ) ) module = AnsibleAWSModule(argument_spec=argument_spec, mutually_exclusive=[['customer_gateway_ids', 'filters']], supports_check_mode=True) if module._module._name == 'ec2_customer_gateway_facts': module._module.deprecate("The 'ec2_customer_gateway_facts' module has been renamed to 'ec2_customer_gateway_info'", version='2.13') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params) list_customer_gateways(connection, module)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(state=dict(required=True, choices=['present', 'absent']), name=dict(required=True), engine=dict(), description=dict(), params=dict(aliases=['parameters'], type='dict'), immediate=dict(type='bool', aliases=['apply_immediately']), tags=dict(type='dict', default={}), purge_tags=dict(type='bool', default=False))) module = AnsibleModule( argument_spec=argument_spec, required_if=[['state', 'present', ['description', 'engine']]]) if not HAS_BOTO3: module.fail_json(msg='boto3 and botocore are required for this module') # Retrieve any AWS settings from the environment. region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True) if not region: module.fail_json(msg="Region must be present") try: conn = boto3_conn(module, conn_type='client', resource='rds', region=region, endpoint=ec2_url, **aws_connect_kwargs) except botocore.exceptions.NoCredentialsError as e: module.fail_json(msg="Couldn't connect to AWS: %s" % str(e)) state = module.params.get('state') if state == 'present': ensure_present(module, conn) if state == 'absent': ensure_absent(module, conn)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(load_balancer_arn=dict(type='str'), target_group_arns=dict(type='list'), names=dict(type='list'), collect_targets_health=dict(default=False, type='bool', required=False))) module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=[[ 'load_balancer_arn', 'target_group_arns', 'names' ]], supports_check_mode=True) if module._name == 'elb_target_group_facts': module.deprecate( "The 'elb_target_group_facts' module has been renamed to 'elb_target_group_info'", version='2.13') if not HAS_BOTO3: module.fail_json(msg='boto3 required for this module') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) if region: connection = boto3_conn(module, conn_type='client', resource='elbv2', region=region, endpoint=ec2_url, **aws_connect_params) else: module.fail_json(msg="region must be specified") list_target_groups(connection, module)
def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict(names=dict(type='list', default=[]))) module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) if module._module._name == 'ec2_placement_group_facts': module._module.deprecate( "The 'ec2_placement_group_facts' module has been renamed to 'ec2_placement_group_info'", version='2.13') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) connection = boto3_conn(module, resource='ec2', conn_type='client', region=region, endpoint=ec2_url, **aws_connect_params) placement_groups = get_placement_groups_details(connection, module) module.exit_json(changed=False, placement_groups=placement_groups)
def __init__(self, ansible_obj, resources, use_boto3=True): try: self.region, self.endpoint, aws_connect_kwargs = get_aws_connection_info( ansible_obj, boto3=use_boto3) self.resource_client = dict() if not resources: resources = ['lambda'] resources.append('iam') for resource in resources: aws_connect_kwargs.update( dict(region=self.region, endpoint=self.endpoint, conn_type='client', resource=resource)) self.resource_client[resource] = boto3_conn( ansible_obj, **aws_connect_kwargs) # if region is not provided, then get default profile/session region if not self.region: self.region = self.resource_client['lambda'].meta.region_name except (ClientError, ParamValidationError, MissingParametersError) as e: ansible_obj.fail_json( msg="Unable to connect, authorize or access resource: {0}". format(e)) # set account ID try: self.account_id = self.resource_client['iam'].get_user( )['User']['Arn'].split(':')[4] except (ClientError, ValueError, KeyError, IndexError): self.account_id = ''
def get_s3_client(module, aws_connect_kwargs, location, ceph, s3_url): if s3_url and ceph: # TODO - test this ceph = urlparse(s3_url) params = dict(module=module, conn_type='client', resource='s3', use_ssl=ceph.scheme == 'https', region=location, endpoint=s3_url, **aws_connect_kwargs) elif is_fakes3(s3_url): fakes3 = urlparse(s3_url) port = fakes3.port if fakes3.scheme == 'fakes3s': protocol = "https" if port is None: port = 443 else: protocol = "http" if port is None: port = 80 params = dict(module=module, conn_type='client', resource='s3', region=location, endpoint="%s://%s:%s" % (protocol, fakes3.hostname, to_text(port)), use_ssl=fakes3.scheme == 'fakes3s', **aws_connect_kwargs) else: params = dict(module=module, conn_type='client', resource='s3', region=location, endpoint=s3_url, **aws_connect_kwargs) return boto3_conn(**params)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( filters=dict(default={}, type='dict'), nat_gateway_ids=dict(default=[], type='list'), )) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if module._name == 'ec2_vpc_nat_gateway_facts': module.deprecate( "The 'ec2_vpc_nat_gateway_facts' module has been renamed to 'ec2_vpc_nat_gateway_info'", version='2.13') # Validate Requirements if not HAS_BOTO3: module.fail_json(msg='botocore/boto3 is required.') try: region, ec2_url, aws_connect_params = get_aws_connection_info( module, boto3=True) if region: connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params) else: module.fail_json(msg="region must be specified") except botocore.exceptions.NoCredentialsError as e: module.fail_json(msg=str(e)) results = get_nat_gateways(connection, module) module.exit_json(result=results)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(snapshot_ids=dict(default=[], type='list'), owner_ids=dict(default=[], type='list'), restorable_by_user_ids=dict(default=[], type='list'), filters=dict(default={}, type='dict'))) module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=[[ 'snapshot_ids', 'owner_ids', 'restorable_by_user_ids', 'filters' ]]) if module._name == 'ec2_snapshot_facts': module.deprecate( "The 'ec2_snapshot_facts' module has been renamed to 'ec2_snapshot_info'", version='2.13') if not HAS_BOTO3: module.fail_json(msg='boto3 required for this module') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) if region: connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params) else: module.fail_json(msg="region must be specified") list_ec2_snapshots(connection, module)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( name=dict(required=False), waf_regional=dict(type='bool', default=False), ) ) module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) if module._name == 'aws_waf_facts': module.deprecate("The 'aws_waf_facts' module has been renamed to 'aws_waf_info'", version='2.13') region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True) resource = 'waf' if not module.params['waf_regional'] else 'waf-regional' client = boto3_conn(module, conn_type='client', resource=resource, region=region, endpoint=ec2_url, **aws_connect_kwargs) web_acls = list_web_acls(client, module) name = module.params['name'] if name: web_acls = [web_acl for web_acl in web_acls if web_acl['Name'] == name] if not web_acls: module.fail_json(msg="WAF named %s not found" % name) module.exit_json(wafs=[get_web_acl(client, module, web_acl['WebACLId']) for web_acl in web_acls])
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(subnet_ids=dict(type='list', default=[], aliases=['subnet_id']), filters=dict(type='dict', default={}))) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if module._name == 'ec2_vpc_subnet_facts': module.deprecate( "The 'ec2_vpc_subnet_facts' module has been renamed to 'ec2_vpc_subnet_info'", version='2.13') if not HAS_BOTO3: module.fail_json(msg='boto3 is required for this module') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) if region: try: connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params) except (botocore.exceptions.NoCredentialsError, botocore.exceptions.ProfileNotFound) as e: module.fail_json(msg=to_native(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) else: module.fail_json(msg="Region must be specified") describe_subnets(connection, module)
def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict(filters=dict(default=None, type='dict'))) module = AnsibleModule(argument_spec=argument_spec) if module._name == 'ec2_eni_facts': module.deprecate( "The 'ec2_eni_facts' module has been renamed to 'ec2_eni_info'", version='2.13') if not HAS_BOTO3: module.fail_json(msg='boto3 required for this module') region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params) list_eni(connection, module)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(stack_name=dict(required=True), template_parameters=dict(required=False, type='dict', default={}), state=dict(default='present', choices=['present', 'absent']), template=dict(default=None, required=False, type='path'), notification_arns=dict(default=None, required=False), stack_policy=dict(default=None, required=False), disable_rollback=dict(default=False, type='bool'), on_create_failure=dict( default=None, required=False, choices=['DO_NOTHING', 'ROLLBACK', 'DELETE']), create_timeout=dict(default=None, type='int'), template_url=dict(default=None, required=False), template_body=dict(default=None, require=False), template_format=dict(default=None, choices=['json', 'yaml'], required=False), create_changeset=dict(default=False, type='bool'), changeset_name=dict(default=None, required=False), role_arn=dict(default=None, required=False), tags=dict(default=None, type='dict'), termination_protection=dict(default=None, type='bool'), events_limit=dict(default=200, type='int'), backoff_retries=dict(type='int', default=10, required=False), backoff_delay=dict(type='int', default=3, required=False), backoff_max_delay=dict(type='int', default=30, required=False), capabilities=dict( type='list', default=['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM']))) module = AnsibleModule( argument_spec=argument_spec, mutually_exclusive=[['template_url', 'template', 'template_body']], supports_check_mode=True) if not HAS_BOTO3: module.fail_json(msg='boto3 and botocore are required for this module') invalid_capabilities = [] user_capabilities = module.params.get('capabilities') for user_cap in user_capabilities: if user_cap not in [ 'CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND' ]: invalid_capabilities.append(user_cap) if invalid_capabilities: module.fail_json(msg="Specified capabilities are invalid : %r," " please check documentation for valid capabilities" % invalid_capabilities) # collect the parameters that are passed to boto3. Keeps us from having so many scalars floating around. stack_params = { 'Capabilities': user_capabilities, 'ClientRequestToken': to_native(uuid.uuid4()), } state = module.params['state'] stack_params['StackName'] = module.params['stack_name'] if module.params['template'] is not None: with open(module.params['template'], 'r') as template_fh: stack_params['TemplateBody'] = template_fh.read() elif module.params['template_body'] is not None: stack_params['TemplateBody'] = module.params['template_body'] elif module.params['template_url'] is not None: stack_params['TemplateURL'] = module.params['template_url'] if module.params.get('notification_arns'): stack_params['NotificationARNs'] = module.params[ 'notification_arns'].split(',') else: stack_params['NotificationARNs'] = [] # can't check the policy when verifying. if module.params[ 'stack_policy'] is not None and not module.check_mode and not module.params[ 'create_changeset']: with open(module.params['stack_policy'], 'r') as stack_policy_fh: stack_params['StackPolicyBody'] = stack_policy_fh.read() template_parameters = module.params['template_parameters'] stack_params['Parameters'] = [] for k, v in template_parameters.items(): if isinstance(v, dict): # set parameter based on a dict to allow additional CFN Parameter Attributes param = dict(ParameterKey=k) if 'value' in v: param['ParameterValue'] = str(v['value']) if 'use_previous_value' in v and bool(v['use_previous_value']): param['UsePreviousValue'] = True param.pop('ParameterValue', None) stack_params['Parameters'].append(param) else: # allow default k/v configuration to set a template parameter stack_params['Parameters'].append({ 'ParameterKey': k, 'ParameterValue': str(v) }) if isinstance(module.params.get('tags'), dict): stack_params['Tags'] = ansible_dict_to_boto3_tag_list( module.params['tags']) if module.params.get('role_arn'): stack_params['RoleARN'] = module.params['role_arn'] result = {} try: region, ec2_url, aws_connect_kwargs = get_aws_connection_info( module, boto3=True) cfn = boto3_conn(module, conn_type='client', resource='cloudformation', region=region, endpoint=ec2_url, **aws_connect_kwargs) except botocore.exceptions.NoCredentialsError as e: module.fail_json(msg=boto_exception(e)) # Wrap the cloudformation client methods that this module uses with # automatic backoff / retry for throttling error codes backoff_wrapper = AWSRetry.jittered_backoff( retries=module.params.get('backoff_retries'), delay=module.params.get('backoff_delay'), max_delay=module.params.get('backoff_max_delay')) cfn.describe_stack_events = backoff_wrapper(cfn.describe_stack_events) cfn.create_stack = backoff_wrapper(cfn.create_stack) cfn.list_change_sets = backoff_wrapper(cfn.list_change_sets) cfn.create_change_set = backoff_wrapper(cfn.create_change_set) cfn.update_stack = backoff_wrapper(cfn.update_stack) cfn.describe_stacks = backoff_wrapper(cfn.describe_stacks) cfn.list_stack_resources = backoff_wrapper(cfn.list_stack_resources) cfn.delete_stack = backoff_wrapper(cfn.delete_stack) if boto_supports_termination_protection(cfn): cfn.update_termination_protection = backoff_wrapper( cfn.update_termination_protection) stack_info = get_stack_facts(cfn, stack_params['StackName']) if module.check_mode: if state == 'absent' and stack_info: module.exit_json(changed=True, msg='Stack would be deleted', meta=[]) elif state == 'absent' and not stack_info: module.exit_json(changed=False, msg='Stack doesn\'t exist', meta=[]) elif state == 'present' and not stack_info: module.exit_json(changed=True, msg='New stack would be created', meta=[]) else: module.exit_json(**check_mode_changeset(module, stack_params, cfn)) if state == 'present': if not stack_info: result = create_stack(module, stack_params, cfn, module.params.get('events_limit')) elif module.params.get('create_changeset'): result = create_changeset(module, stack_params, cfn, module.params.get('events_limit')) else: if module.params.get('termination_protection') is not None: update_termination_protection( module, cfn, stack_params['StackName'], bool(module.params.get('termination_protection'))) result = update_stack(module, stack_params, cfn, module.params.get('events_limit')) # format the stack output stack = get_stack_facts(cfn, stack_params['StackName']) if stack is not None: if result.get('stack_outputs') is None: # always define stack_outputs, but it may be empty result['stack_outputs'] = {} for output in stack.get('Outputs', []): result['stack_outputs'][ output['OutputKey']] = output['OutputValue'] stack_resources = [] reslist = cfn.list_stack_resources( StackName=stack_params['StackName']) for res in reslist.get('StackResourceSummaries', []): stack_resources.append({ "logical_resource_id": res['LogicalResourceId'], "physical_resource_id": res.get('PhysicalResourceId', ''), "resource_type": res['ResourceType'], "last_updated_time": res['LastUpdatedTimestamp'], "status": res['ResourceStatus'], "status_reason": res.get('ResourceStatusReason') # can be blank, apparently }) result['stack_resources'] = stack_resources elif state == 'absent': # absent state is different because of the way delete_stack works. # problem is it it doesn't give an error if stack isn't found # so must describe the stack first try: stack = get_stack_facts(cfn, stack_params['StackName']) if not stack: result = {'changed': False, 'output': 'Stack not found.'} else: if stack_params.get('RoleARN') is None: cfn.delete_stack(StackName=stack_params['StackName']) else: cfn.delete_stack(StackName=stack_params['StackName'], RoleARN=stack_params['RoleARN']) result = stack_operation( cfn, stack_params['StackName'], 'DELETE', module.params.get('events_limit'), stack_params.get('ClientRequestToken', None)) except Exception as err: module.fail_json(msg=boto_exception(err), exception=traceback.format_exc()) if module.params['template_format'] is not None: result['warnings'] = [ ('Argument `template_format` is deprecated ' 'since Ansible 2.3, JSON and YAML templates are now passed ' 'directly to the CloudFormation API.') ] module.exit_json(**result)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(log_group_name=dict(required=True, type='str'), state=dict(choices=['present', 'absent'], default='present'), kms_key_id=dict(required=False, type='str'), tags=dict(required=False, type='dict'), retention=dict(required=False, type='int'), purge_retention_policy=dict(required=False, type='bool', default=False), overwrite=dict(required=False, type='bool', default=False))) mutually_exclusive = [['retention', 'purge_retention_policy'], ['purge_retention_policy', 'overwrite']] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive) if not HAS_BOTO3: module.fail_json(msg='boto3 is required.') region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True) logs = boto3_conn(module, conn_type='client', resource='logs', region=region, endpoint=ec2_url, **aws_connect_kwargs) state = module.params.get('state') changed = False # Determine if the log group exists desc_log_group = describe_log_group( client=logs, log_group_name=module.params['log_group_name'], module=module) found_log_group = {} for i in desc_log_group.get('logGroups', []): if module.params['log_group_name'] == i['logGroupName']: found_log_group = i break if state == 'present': if found_log_group: if module.params['overwrite'] is True: changed = True delete_log_group( client=logs, log_group_name=module.params['log_group_name'], module=module) found_log_group = create_log_group( client=logs, log_group_name=module.params['log_group_name'], kms_key_id=module.params['kms_key_id'], tags=module.params['tags'], retention=module.params['retention'], module=module) elif module.params['purge_retention_policy']: if found_log_group.get('retentionInDays'): changed = True delete_retention_policy( client=logs, log_group_name=module.params['log_group_name'], module=module) elif module.params['retention'] != found_log_group.get( 'retentionInDays'): if module.params['retention'] is not None: changed = True input_retention_policy( client=logs, log_group_name=module.params['log_group_name'], retention=module.params['retention'], module=module) found_log_group['retentionInDays'] = module.params[ 'retention'] elif not found_log_group: changed = True found_log_group = create_log_group( client=logs, log_group_name=module.params['log_group_name'], kms_key_id=module.params['kms_key_id'], tags=module.params['tags'], retention=module.params['retention'], module=module) module.exit_json(changed=changed, **camel_dict_to_snake_dict(found_log_group)) elif state == 'absent': if found_log_group: changed = True delete_log_group(client=logs, log_group_name=module.params['log_group_name'], module=module) module.exit_json(changed=changed)
def setup_client(module): region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True) connection = boto3_conn(module, conn_type='client', resource='ssm', region=region, endpoint=ec2_url, **aws_connect_params) return connection
def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict( name=dict(), function_arn=dict(), wait=dict(default=True, type='bool'), tail_log=dict(default=False, type='bool'), dry_run=dict(default=False, type='bool'), version_qualifier=dict(), payload=dict(default={}, type='dict'), )) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, mutually_exclusive=[ ['name', 'function_arn'], ] ) if not HAS_BOTO3: module.fail_json(msg='boto3 required for this module') name = module.params.get('name') function_arn = module.params.get('function_arn') await_return = module.params.get('wait') dry_run = module.params.get('dry_run') tail_log = module.params.get('tail_log') version_qualifier = module.params.get('version_qualifier') payload = module.params.get('payload') if not HAS_BOTO3: module.fail_json(msg='Python module "boto3" is missing, please install it') if not (name or function_arn): module.fail_json(msg="Must provide either a function_arn or a name to invoke.") region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=HAS_BOTO3) if not region: module.fail_json(msg="The AWS region must be specified as an " "environment variable or in the AWS credentials " "profile.") try: client = boto3_conn(module, conn_type='client', resource='lambda', region=region, endpoint=ec2_url, **aws_connect_kwargs) except (botocore.exceptions.ClientError, botocore.exceptions.ValidationError) as e: module.fail_json(msg="Failure connecting boto3 to AWS: %s" % to_native(e), exception=traceback.format_exc()) invoke_params = {} if await_return: # await response invoke_params['InvocationType'] = 'RequestResponse' else: # fire and forget invoke_params['InvocationType'] = 'Event' if dry_run or module.check_mode: # dry_run overrides invocation type invoke_params['InvocationType'] = 'DryRun' if tail_log and await_return: invoke_params['LogType'] = 'Tail' elif tail_log and not await_return: module.fail_json(msg="The `tail_log` parameter is only available if " "the invocation waits for the function to complete. " "Set `wait` to true or turn off `tail_log`.") else: invoke_params['LogType'] = 'None' if version_qualifier: invoke_params['Qualifier'] = version_qualifier if payload: invoke_params['Payload'] = json.dumps(payload) if function_arn: invoke_params['FunctionName'] = function_arn elif name: invoke_params['FunctionName'] = name try: response = client.invoke(**invoke_params) except botocore.exceptions.ClientError as ce: if ce.response['Error']['Code'] == 'ResourceNotFoundException': module.fail_json(msg="Could not find Lambda to execute. Make sure " "the ARN is correct and your profile has " "permissions to execute this function.", exception=traceback.format_exc()) module.fail_json(msg="Client-side error when invoking Lambda, check inputs and specific error", exception=traceback.format_exc()) except botocore.exceptions.ParamValidationError as ve: module.fail_json(msg="Parameters to `invoke` failed to validate", exception=traceback.format_exc()) except Exception as e: module.fail_json(msg="Unexpected failure while invoking Lambda function", exception=traceback.format_exc()) results = { 'logs': '', 'status': response['StatusCode'], 'output': '', } if response.get('LogResult'): try: # logs are base64 encoded in the API response results['logs'] = base64.b64decode(response.get('LogResult', '')) except Exception as e: module.fail_json(msg="Failed while decoding logs", exception=traceback.format_exc()) if invoke_params['InvocationType'] == 'RequestResponse': try: results['output'] = json.loads(response['Payload'].read().decode('utf8')) except Exception as e: module.fail_json(msg="Failed while decoding function return value", exception=traceback.format_exc()) if isinstance(results.get('output'), dict) and any( [results['output'].get('stackTrace'), results['output'].get('errorMessage')]): # AWS sends back stack traces and error messages when a function failed # in a RequestResponse (synchronous) context. template = ("Function executed, but there was an error in the Lambda function. " "Message: {errmsg}, Type: {type}, Stack Trace: {trace}") error_data = { # format the stacktrace sent back as an array into a multiline string 'trace': '\n'.join( [' '.join([ str(x) for x in line # cast line numbers to strings ]) for line in results.get('output', {}).get('stackTrace', [])] ), 'errmsg': results['output'].get('errorMessage'), 'type': results['output'].get('errorType') } module.fail_json(msg=template.format(**error_data), result=results) module.exit_json(changed=True, result=results)
def create_launch_config(connection, module): name = module.params.get('name') vpc_id = module.params.get('vpc_id') try: region, ec2_url, aws_connect_kwargs = get_aws_connection_info( module, boto3=True) ec2_connection = boto3_conn(module, 'client', 'ec2', region, ec2_url, **aws_connect_kwargs) security_groups = get_ec2_security_group_ids_from_names( module.params.get('security_groups'), ec2_connection, vpc_id=vpc_id, boto3=True) except botocore.exceptions.ClientError as e: module.fail_json(msg="Failed to get Security Group IDs", exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) except ValueError as e: module.fail_json(msg="Failed to get Security Group IDs", exception=traceback.format_exc()) user_data = module.params.get('user_data') user_data_path = module.params.get('user_data_path') volumes = module.params['volumes'] instance_monitoring = module.params.get('instance_monitoring') assign_public_ip = module.params.get('assign_public_ip') instance_profile_name = module.params.get('instance_profile_name') ebs_optimized = module.params.get('ebs_optimized') classic_link_vpc_id = module.params.get('classic_link_vpc_id') classic_link_vpc_security_groups = module.params.get( 'classic_link_vpc_security_groups') block_device_mapping = [] convert_list = [ 'image_id', 'instance_type', 'instance_type', 'instance_id', 'placement_tenancy', 'key_name', 'kernel_id', 'ramdisk_id', 'spot_price' ] launch_config = (snake_dict_to_camel_dict( dict((k.capitalize(), str(v)) for k, v in module.params.items() if v is not None and k in convert_list))) if user_data_path: try: with open(user_data_path, 'r') as user_data_file: user_data = user_data_file.read() except IOError as e: module.fail_json(msg="Failed to open file for reading", exception=traceback.format_exc()) if volumes: for volume in volumes: if 'device_name' not in volume: module.fail_json(msg='Device name must be set for volume') # Minimum volume size is 1GiB. We'll use volume size explicitly set to 0 to be a signal not to create this volume if 'volume_size' not in volume or int(volume['volume_size']) > 0: block_device_mapping.append( create_block_device_meta(module, volume)) try: launch_configs = connection.describe_launch_configurations( LaunchConfigurationNames=[name]).get('LaunchConfigurations') except botocore.exceptions.ClientError as e: module.fail_json(msg="Failed to describe launch configuration by name", exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) changed = False result = {} launch_config['LaunchConfigurationName'] = name if security_groups is not None: launch_config['SecurityGroups'] = security_groups if classic_link_vpc_id is not None: launch_config['ClassicLinkVPCId'] = classic_link_vpc_id if instance_monitoring is not None: launch_config['InstanceMonitoring'] = {'Enabled': instance_monitoring} if classic_link_vpc_security_groups is not None: launch_config[ 'ClassicLinkVPCSecurityGroups'] = classic_link_vpc_security_groups if block_device_mapping: launch_config['BlockDeviceMappings'] = block_device_mapping if instance_profile_name is not None: launch_config['IamInstanceProfile'] = instance_profile_name if assign_public_ip is not None: launch_config['AssociatePublicIpAddress'] = assign_public_ip if user_data is not None: launch_config['UserData'] = user_data if ebs_optimized is not None: launch_config['EbsOptimized'] = ebs_optimized if len(launch_configs) == 0: try: connection.create_launch_configuration(**launch_config) launch_configs = connection.describe_launch_configurations( LaunchConfigurationNames=[name]).get('LaunchConfigurations') changed = True if launch_configs: launch_config = launch_configs[0] except botocore.exceptions.ClientError as e: module.fail_json(msg="Failed to create launch configuration", exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) result = (dict((k, v) for k, v in launch_config.items() if k not in [ 'Connection', 'CreatedTime', 'InstanceMonitoring', 'BlockDeviceMappings' ])) result['CreatedTime'] = to_text(launch_config.get('CreatedTime')) try: result['InstanceMonitoring'] = module.boolean( launch_config.get('InstanceMonitoring').get('Enabled')) except AttributeError: result['InstanceMonitoring'] = False result['BlockDeviceMappings'] = [] for block_device_mapping in launch_config.get('BlockDeviceMappings', []): result['BlockDeviceMappings'].append( dict(device_name=block_device_mapping.get('DeviceName'), virtual_name=block_device_mapping.get('VirtualName'))) if block_device_mapping.get('Ebs') is not None: result['BlockDeviceMappings'][-1]['ebs'] = dict( snapshot_id=block_device_mapping.get('Ebs').get('SnapshotId'), volume_size=block_device_mapping.get('Ebs').get('VolumeSize')) if user_data_path: result[ 'UserData'] = "hidden" # Otherwise, we dump binary to the user's terminal return_object = { 'Name': result.get('LaunchConfigurationName'), 'CreatedTime': result.get('CreatedTime'), 'ImageId': result.get('ImageId'), 'Arn': result.get('LaunchConfigurationARN'), 'SecurityGroups': result.get('SecurityGroups'), 'InstanceType': result.get('InstanceType'), 'Result': result } module.exit_json(changed=changed, **camel_dict_to_snake_dict(return_object))
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( vpc_id=dict(), service=dict(), policy=dict(type='json'), policy_file=dict(type='path', aliases=['policy_path']), state=dict(default='present', choices=['present', 'absent']), wait=dict(type='bool', default=False), wait_timeout=dict(type='int', default=320, required=False), route_table_ids=dict(type='list'), vpc_endpoint_id=dict(), client_token=dict(), )) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, mutually_exclusive=[['policy', 'policy_file']], required_if=[ ['state', 'present', ['vpc_id', 'service']], ['state', 'absent', ['vpc_endpoint_id']], ]) # Validate Requirements if not HAS_BOTO3: module.fail_json(msg='botocore and boto3 are required for this module') state = module.params.get('state') try: region, ec2_url, aws_connect_kwargs = get_aws_connection_info( module, boto3=True) except NameError as e: # Getting around the get_aws_connection_info boto reliance for region if "global name 'boto' is not defined" in e.message: module.params['region'] = botocore.session.get_session( ).get_config_variable('region') if not module.params['region']: module.fail_json(msg="Error - no region provided") else: module.fail_json(msg="Can't retrieve connection information - " + str(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) try: region, ec2_url, aws_connect_kwargs = get_aws_connection_info( module, boto3=True) ec2 = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_kwargs) except botocore.exceptions.NoCredentialsError as e: module.fail_json( msg= "Failed to connect to AWS due to wrong or missing credentials: %s" % str(e), exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response)) # Ensure resource is present if state == 'present': (changed, results) = setup_creation(ec2, module) else: (changed, results) = setup_removal(ec2, module) module.exit_json(changed=changed, result=results)