Added the OnFailure option to the AWS CloudFormation module (#52431)

* Added the OnFailure option to the AWS CloudFormation module

* Added unit tests for CloudFormation `on_create_failure`
pull/55227/head
Nathan Dines 5 years ago committed by Jill R
parent e40832df84
commit 5eb3117822

@ -33,6 +33,14 @@ options:
- If a stacks fails to form, rollback will remove the stack
type: bool
default: 'no'
on_create_failure:
description:
- Action to take upon failure of stack creation. Incompatible with the disable_rollback option.
choices:
- DO_NOTHING
- ROLLBACK
- DELETE
version_added: "2.8"
create_timeout:
description:
- The amount of time (in minutes) that can pass before the stack status becomes CREATE_FAILED
@ -259,6 +267,17 @@ EXAMPLES = '''
template_url: https://s3.amazonaws.com/my-bucket/cloudformation.template
create_timeout: 5
# Configure rollback behaviour on the unsuccessful creation of a stack allowing
# CloudFormation to clean up, or do nothing in the event of an unsuccessful
# deployment
# In this case, if on_create_failure is set to "DELETE", it will clean up the stack if
# it fails to create
- name: create stack which will delete on creation failure
cloudformation:
stack_name: my_stack
state: present
template_url: https://s3.amazonaws.com/my-bucket/cloudformation.template
on_create_failure: DELETE
'''
RETURN = '''
@ -354,9 +373,17 @@ def create_stack(module, stack_params, cfn, events_limit):
if 'TemplateBody' not in stack_params and 'TemplateURL' not in stack_params:
module.fail_json(msg="Either 'template', 'template_body' or 'template_url' is required when the stack does not exist.")
# 'DisableRollback', 'TimeoutInMinutes' and 'EnableTerminationProtection'
# only apply on creation, not update.
stack_params['DisableRollback'] = module.params['disable_rollback']
# 'DisableRollback', 'TimeoutInMinutes', 'EnableTerminationProtection' and
# 'OnFailure' only apply on creation, not update.
#
# 'OnFailure' and 'DisableRollback' are incompatible with each other, so
# throw error if both are defined
if module.params.get('on_create_failure') is None:
stack_params['DisableRollback'] = module.params['disable_rollback']
else:
if module.params['disable_rollback']:
module.fail_json(msg="You can specify either 'on_create_failure' or 'disable_rollback', but not both.")
stack_params['OnFailure'] = module.params['on_create_failure']
if module.params.get('create_timeout') is not None:
stack_params['TimeoutInMinutes'] = module.params['create_timeout']
if module.params.get('termination_protection') is not None:
@ -366,8 +393,9 @@ def create_stack(module, stack_params, cfn, events_limit):
module.fail_json(msg="termination_protection parameter requires botocore >= 1.7.18")
try:
cfn.create_stack(**stack_params)
result = stack_operation(cfn, stack_params['StackName'], 'CREATE', events_limit, stack_params.get('ClientRequestToken', None))
response = cfn.create_stack(**stack_params)
# Use stack ID to follow stack state in case of on_create_failure = DELETE
result = stack_operation(cfn, response['StackId'], 'CREATE', events_limit, stack_params.get('ClientRequestToken', None))
except Exception as err:
error_msg = boto_exception(err)
module.fail_json(msg="Failed to create stack {0}: {1}.".format(stack_params.get('StackName'), error_msg), exception=traceback.format_exc())
@ -509,7 +537,10 @@ def stack_operation(cfn, stack_name, operation, events_limit, op_token=None):
elif stack['StackStatus'].endswith('ROLLBACK_COMPLETE') and operation != 'CREATE_CHANGESET':
ret.update({'changed': True, 'failed': True, 'output': 'Problem with %s. Rollback complete' % operation})
return ret
# note the ordering of ROLLBACK_COMPLETE and COMPLETE, because otherwise COMPLETE will match both cases.
elif stack['StackStatus'] == 'DELETE_COMPLETE' and operation == 'CREATE':
ret.update({'changed': True, 'failed': True, 'output': 'Stack create failed. Delete complete.'})
return ret
# note the ordering of ROLLBACK_COMPLETE, DELETE_COMPLETE, and COMPLETE, because otherwise COMPLETE will match all cases.
elif stack['StackStatus'].endswith('_COMPLETE'):
ret.update({'changed': True, 'output': 'Stack %s complete' % operation})
return ret
@ -599,6 +630,7 @@ def main():
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),
@ -738,23 +770,24 @@ def main():
# format the stack output
stack = get_stack_facts(cfn, stack_params['StackName'])
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
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.

@ -0,0 +1,17 @@
{
"status_code": 200,
"data": {
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResponseMetadata": {
"RequestId": "c741ebcd-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "c741ebcd-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "407",
"date": "Tue, 26 Feb 2019 21:37:55 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,38 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "c74b1310-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "c7b0b337-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "c7b0b337-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "1153",
"date": "Tue, 26 Feb 2019 21:37:56 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,101 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_FAILED-2019-02-26T21:38:01.107Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 1,
"microsecond": 107000
},
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Invalid repository policy provided' (Service: AmazonECR; Status Code: 400; Error Code: InvalidParameterException; Request ID: ca5769ae-3a0e-11e9-a183-3f277586a4cb)",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:38:00.657Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 0,
"microsecond": 657000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "Resource creation Initiated",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:38:00.221Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 0,
"microsecond": 221000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "c74b1310-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "caf667e9-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "caf667e9-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "4312",
"vary": "Accept-Encoding",
"date": "Tue, 26 Feb 2019 21:38:01 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,121 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "cafc8250-3a0e-11e9-86c5-02035744c0fa",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 2,
"microsecond": 76000
},
"ResourceStatus": "DELETE_IN_PROGRESS",
"ResourceStatusReason": "The following resource(s) failed to create: [ECRRepo]. . Delete requested by user."
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_FAILED-2019-02-26T21:38:01.107Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 1,
"microsecond": 107000
},
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Invalid repository policy provided' (Service: AmazonECR; Status Code: 400; Error Code: InvalidParameterException; Request ID: ca5769ae-3a0e-11e9-a183-3f277586a4cb)",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:38:00.657Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 0,
"microsecond": 657000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "Resource creation Initiated",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:38:00.221Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 0,
"microsecond": 221000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "c74b1310-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "ce498af1-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "ce498af1-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "5207",
"vary": "Accept-Encoding",
"date": "Tue, 26 Feb 2019 21:38:06 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,180 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "d19c8600-3a0e-11e9-a4ba-0a3524ef8042",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 13,
"microsecond": 177000
},
"ResourceStatus": "DELETE_COMPLETE"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-DELETE_COMPLETE-2019-02-26T21:38:12.486Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 12,
"microsecond": 486000
},
"ResourceStatus": "DELETE_COMPLETE",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-DELETE_IN_PROGRESS-2019-02-26T21:38:12.139Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 12,
"microsecond": 139000
},
"ResourceStatus": "DELETE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "cafc8250-3a0e-11e9-86c5-02035744c0fa",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 2,
"microsecond": 76000
},
"ResourceStatus": "DELETE_IN_PROGRESS",
"ResourceStatusReason": "The following resource(s) failed to create: [ECRRepo]. . Delete requested by user."
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_FAILED-2019-02-26T21:38:01.107Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 1,
"microsecond": 107000
},
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Invalid repository policy provided' (Service: AmazonECR; Status Code: 400; Error Code: InvalidParameterException; Request ID: ca5769ae-3a0e-11e9-a183-3f277586a4cb)",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:38:00.657Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 0,
"microsecond": 657000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "Resource creation Initiated",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:38:00.221Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 0,
"microsecond": 221000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "c74b1310-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "d19fbb1b-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "d19fbb1b-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "7857",
"vary": "Accept-Encoding",
"date": "Tue, 26 Feb 2019 21:38:12 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,180 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "d19c8600-3a0e-11e9-a4ba-0a3524ef8042",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 13,
"microsecond": 177000
},
"ResourceStatus": "DELETE_COMPLETE"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-DELETE_COMPLETE-2019-02-26T21:38:12.486Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 12,
"microsecond": 486000
},
"ResourceStatus": "DELETE_COMPLETE",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-DELETE_IN_PROGRESS-2019-02-26T21:38:12.139Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 12,
"microsecond": 139000
},
"ResourceStatus": "DELETE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "cafc8250-3a0e-11e9-86c5-02035744c0fa",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 2,
"microsecond": 76000
},
"ResourceStatus": "DELETE_IN_PROGRESS",
"ResourceStatusReason": "The following resource(s) failed to create: [ECRRepo]. . Delete requested by user."
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_FAILED-2019-02-26T21:38:01.107Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 1,
"microsecond": 107000
},
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Invalid repository policy provided' (Service: AmazonECR; Status Code: 400; Error Code: InvalidParameterException; Request ID: ca5769ae-3a0e-11e9-a183-3f277586a4cb)",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:38:00.657Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-8jlpw72yz5x8",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 0,
"microsecond": 657000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "Resource creation Initiated",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:38:00.221Z",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 0,
"microsecond": 221000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"EventId": "c74b1310-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"LogicalResourceId": "ansible-test-on-create-failure-delete",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "d4fbddab-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "d4fbddab-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "7857",
"vary": "Accept-Encoding",
"date": "Tue, 26 Feb 2019 21:38:18 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,42 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"RollbackConfiguration": {},
"StackStatus": "CREATE_IN_PROGRESS",
"StackStatusReason": "User Initiated",
"DisableRollback": false,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "c77fb823-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "c77fb823-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "1041",
"date": "Tue, 26 Feb 2019 21:37:56 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,41 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"RollbackConfiguration": {},
"StackStatus": "CREATE_IN_PROGRESS",
"DisableRollback": false,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "cad153b2-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "cad153b2-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "979",
"date": "Tue, 26 Feb 2019 21:38:01 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,52 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"DeletionTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 2,
"microsecond": 76000
},
"RollbackConfiguration": {},
"StackStatus": "DELETE_IN_PROGRESS",
"StackStatusReason": "The following resource(s) failed to create: [ECRRepo]. . Delete requested by user.",
"DisableRollback": false,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "ce24289a-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "ce24289a-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "1171",
"date": "Tue, 26 Feb 2019 21:38:06 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,51 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"DeletionTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 2,
"microsecond": 76000
},
"RollbackConfiguration": {},
"StackStatus": "DELETE_IN_PROGRESS",
"DisableRollback": false,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "d16c27f2-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "d16c27f2-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "1041",
"date": "Tue, 26 Feb 2019 21:38:12 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,50 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-delete/c74a4fc0-3a0e-11e9-9a48-067794494828",
"StackName": "ansible-test-on-create-failure-delete",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 37,
"second": 55,
"microsecond": 909000
},
"DeletionTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 38,
"second": 2,
"microsecond": 76000
},
"RollbackConfiguration": {},
"StackStatus": "DELETE_COMPLETE",
"DisableRollback": false,
"NotificationARNs": [],
"Tags": [],
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "d4c90dd6-3a0e-11e9-b25f-d1217e6893bf",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "d4c90dd6-3a0e-11e9-b25f-d1217e6893bf",
"content-type": "text/xml",
"content-length": "965",
"date": "Tue, 26 Feb 2019 21:38:18 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,17 @@
{
"status_code": 200,
"data": {
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"ResponseMetadata": {
"RequestId": "a396a58a-3a0f-11e9-b7db-3fe3824c73cb",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "a396a58a-3a0f-11e9-b7db-3fe3824c73cb",
"content-type": "text/xml",
"content-length": "411",
"date": "Tue, 26 Feb 2019 21:44:05 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,16 @@
{
"status_code": 200,
"data": {
"ResponseMetadata": {
"RequestId": "a78f0832-3a0f-11e9-b7db-3fe3824c73cb",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "a78f0832-3a0f-11e9-b7db-3fe3824c73cb",
"content-type": "text/xml",
"content-length": "212",
"date": "Tue, 26 Feb 2019 21:44:11 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,38 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"EventId": "a39e6ce0-3a0f-11e9-96ca-02f46dd00950",
"StackName": "ansible-test-on-create-failure-do-nothing",
"LogicalResourceId": "ansible-test-on-create-failure-do-nothing",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 44,
"second": 5,
"microsecond": 553000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "a406cc84-3a0f-11e9-b7db-3fe3824c73cb",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "a406cc84-3a0f-11e9-b7db-3fe3824c73cb",
"content-type": "text/xml",
"content-length": "1169",
"date": "Tue, 26 Feb 2019 21:44:06 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,121 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"EventId": "a6c32c80-3a0f-11e9-ac5e-06deb474fa52",
"StackName": "ansible-test-on-create-failure-do-nothing",
"LogicalResourceId": "ansible-test-on-create-failure-do-nothing",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 44,
"second": 10,
"microsecond": 804000
},
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "The following resource(s) failed to create: [ECRRepo]. "
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"EventId": "ECRRepo-CREATE_FAILED-2019-02-26T21:44:09.905Z",
"StackName": "ansible-test-on-create-failure-do-nothing",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-a8g0mh5il4t5",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 44,
"second": 9,
"microsecond": 905000
},
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Invalid repository policy provided' (Service: AmazonECR; Status Code: 400; Error Code: InvalidParameterException; Request ID: a62a6f71-3a0f-11e9-9164-457e0a3a5e1b)",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:44:09.497Z",
"StackName": "ansible-test-on-create-failure-do-nothing",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-a8g0mh5il4t5",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 44,
"second": 9,
"microsecond": 497000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "Resource creation Initiated",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:44:09.076Z",
"StackName": "ansible-test-on-create-failure-do-nothing",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 44,
"second": 9,
"microsecond": 76000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"EventId": "a39e6ce0-3a0f-11e9-96ca-02f46dd00950",
"StackName": "ansible-test-on-create-failure-do-nothing",
"LogicalResourceId": "ansible-test-on-create-failure-do-nothing",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 44,
"second": 5,
"microsecond": 553000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "a75fbad0-3a0f-11e9-b7db-3fe3824c73cb",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "a75fbad0-3a0f-11e9-b7db-3fe3824c73cb",
"content-type": "text/xml",
"content-length": "5231",
"vary": "Accept-Encoding",
"date": "Tue, 26 Feb 2019 21:44:11 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,42 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"StackName": "ansible-test-on-create-failure-do-nothing",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 44,
"second": 5,
"microsecond": 553000
},
"RollbackConfiguration": {},
"StackStatus": "CREATE_IN_PROGRESS",
"StackStatusReason": "User Initiated",
"DisableRollback": true,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "a3d44acf-3a0f-11e9-b7db-3fe3824c73cb",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "a3d44acf-3a0f-11e9-b7db-3fe3824c73cb",
"content-type": "text/xml",
"content-length": "1048",
"date": "Tue, 26 Feb 2019 21:44:05 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,42 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-do-nothing/a39dd0a0-3a0f-11e9-96ca-02f46dd00950",
"StackName": "ansible-test-on-create-failure-do-nothing",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 44,
"second": 5,
"microsecond": 553000
},
"RollbackConfiguration": {},
"StackStatus": "CREATE_FAILED",
"StackStatusReason": "The following resource(s) failed to create: [ECRRepo]. ",
"DisableRollback": true,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "a7301f4a-3a0f-11e9-b7db-3fe3824c73cb",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "a7301f4a-3a0f-11e9-b7db-3fe3824c73cb",
"content-type": "text/xml",
"content-length": "1084",
"date": "Tue, 26 Feb 2019 21:44:11 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,17 @@
{
"status_code": 200,
"data": {
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"ResponseMetadata": {
"RequestId": "9139de54-3a0f-11e9-b938-97983b40cabe",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "9139de54-3a0f-11e9-b938-97983b40cabe",
"content-type": "text/xml",
"content-length": "409",
"date": "Tue, 26 Feb 2019 21:43:34 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,16 @@
{
"status_code": 200,
"data": {
"ResponseMetadata": {
"RequestId": "988b3097-3a0f-11e9-b938-97983b40cabe",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "988b3097-3a0f-11e9-b938-97983b40cabe",
"content-type": "text/xml",
"content-length": "212",
"date": "Tue, 26 Feb 2019 21:43:46 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,38 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "9140bc10-3a0f-11e9-94bf-0a9edf17d014",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ansible-test-on-create-failure-rollback",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 34,
"microsecond": 740000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "9199b1a7-3a0f-11e9-b938-97983b40cabe",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "9199b1a7-3a0f-11e9-b938-97983b40cabe",
"content-type": "text/xml",
"content-length": "1161",
"date": "Tue, 26 Feb 2019 21:43:35 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,121 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "945b90a0-3a0f-11e9-adaf-0211d8bec7e2",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ansible-test-on-create-failure-rollback",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 39,
"microsecond": 920000
},
"ResourceStatus": "ROLLBACK_IN_PROGRESS",
"ResourceStatusReason": "The following resource(s) failed to create: [ECRRepo]. . Rollback requested by user."
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "ECRRepo-CREATE_FAILED-2019-02-26T21:43:39.210Z",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-1lsnxu2zpb20l",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 39,
"microsecond": 210000
},
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Invalid repository policy provided' (Service: AmazonECR; Status Code: 400; Error Code: InvalidParameterException; Request ID: 93e0bb60-3a0f-11e9-a53c-7162bb423e4d)",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:43:38.793Z",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-1lsnxu2zpb20l",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 38,
"microsecond": 793000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "Resource creation Initiated",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:43:38.266Z",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 38,
"microsecond": 266000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "9140bc10-3a0f-11e9-94bf-0a9edf17d014",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ansible-test-on-create-failure-rollback",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 34,
"microsecond": 740000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "94e16307-3a0f-11e9-b938-97983b40cabe",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "94e16307-3a0f-11e9-b938-97983b40cabe",
"content-type": "text/xml",
"content-length": "5241",
"vary": "Accept-Encoding",
"date": "Tue, 26 Feb 2019 21:43:40 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,180 @@
{
"status_code": 200,
"data": {
"StackEvents": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "9743bc70-3a0f-11e9-b335-0ade61d04ee6",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ansible-test-on-create-failure-rollback",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 44,
"microsecond": 797000
},
"ResourceStatus": "ROLLBACK_COMPLETE"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "ECRRepo-DELETE_COMPLETE-2019-02-26T21:43:43.908Z",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-1lsnxu2zpb20l",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 43,
"microsecond": 908000
},
"ResourceStatus": "DELETE_COMPLETE",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "ECRRepo-DELETE_IN_PROGRESS-2019-02-26T21:43:43.478Z",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-1lsnxu2zpb20l",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 43,
"microsecond": 478000
},
"ResourceStatus": "DELETE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "945b90a0-3a0f-11e9-adaf-0211d8bec7e2",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ansible-test-on-create-failure-rollback",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 39,
"microsecond": 920000
},
"ResourceStatus": "ROLLBACK_IN_PROGRESS",
"ResourceStatusReason": "The following resource(s) failed to create: [ECRRepo]. . Rollback requested by user."
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "ECRRepo-CREATE_FAILED-2019-02-26T21:43:39.210Z",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-1lsnxu2zpb20l",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 39,
"microsecond": 210000
},
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Invalid repository policy provided' (Service: AmazonECR; Status Code: 400; Error Code: InvalidParameterException; Request ID: 93e0bb60-3a0f-11e9-a53c-7162bb423e4d)",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:43:38.793Z",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "ansib-ecrre-1lsnxu2zpb20l",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 38,
"microsecond": 793000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "Resource creation Initiated",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "ECRRepo-CREATE_IN_PROGRESS-2019-02-26T21:43:38.266Z",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ECRRepo",
"PhysicalResourceId": "",
"ResourceType": "AWS::ECR::Repository",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 38,
"microsecond": 266000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceProperties": "{\"RepositoryPolicyText\":{\"Version\":\"3000-10-17\",\"Statement\":[{\"Action\":[\"ecr:*\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"}}]}}"
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"EventId": "9140bc10-3a0f-11e9-94bf-0a9edf17d014",
"StackName": "ansible-test-on-create-failure-rollback",
"LogicalResourceId": "ansible-test-on-create-failure-rollback",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 34,
"microsecond": 740000
},
"ResourceStatus": "CREATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
}
],
"ResponseMetadata": {
"RequestId": "982d0bff-3a0f-11e9-b938-97983b40cabe",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "982d0bff-3a0f-11e9-b938-97983b40cabe",
"content-type": "text/xml",
"content-length": "7911",
"vary": "Accept-Encoding",
"date": "Tue, 26 Feb 2019 21:43:45 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,42 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"StackName": "ansible-test-on-create-failure-rollback",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 34,
"microsecond": 740000
},
"RollbackConfiguration": {},
"StackStatus": "CREATE_IN_PROGRESS",
"StackStatusReason": "User Initiated",
"DisableRollback": false,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "91725383-3a0f-11e9-b938-97983b40cabe",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "91725383-3a0f-11e9-b938-97983b40cabe",
"content-type": "text/xml",
"content-length": "1045",
"date": "Tue, 26 Feb 2019 21:43:35 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,52 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"StackName": "ansible-test-on-create-failure-rollback",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 34,
"microsecond": 740000
},
"DeletionTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 39,
"microsecond": 920000
},
"RollbackConfiguration": {},
"StackStatus": "ROLLBACK_IN_PROGRESS",
"StackStatusReason": "The following resource(s) failed to create: [ECRRepo]. . Rollback requested by user.",
"DisableRollback": false,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "94bb1651-3a0f-11e9-b938-97983b40cabe",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "94bb1651-3a0f-11e9-b938-97983b40cabe",
"content-type": "text/xml",
"content-length": "1179",
"date": "Tue, 26 Feb 2019 21:43:40 GMT"
},
"RetryAttempts": 0
}
}
}

@ -0,0 +1,51 @@
{
"status_code": 200,
"data": {
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/ansible-test-on-create-failure-rollback/914046e0-3a0f-11e9-94bf-0a9edf17d014",
"StackName": "ansible-test-on-create-failure-rollback",
"CreationTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 34,
"microsecond": 740000
},
"DeletionTime": {
"__class__": "datetime",
"year": 2019,
"month": 2,
"day": 26,
"hour": 21,
"minute": 43,
"second": 39,
"microsecond": 920000
},
"RollbackConfiguration": {},
"StackStatus": "ROLLBACK_COMPLETE",
"DisableRollback": false,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
],
"ResponseMetadata": {
"RequestId": "98016814-3a0f-11e9-b938-97983b40cabe",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "98016814-3a0f-11e9-b938-97983b40cabe",
"content-type": "text/xml",
"content-length": "1044",
"date": "Tue, 26 Feb 2019 21:43:45 GMT"
},
"RetryAttempts": 0
}
}
}

@ -44,6 +44,23 @@ bad_json_tpl = """{
}
}"""
failing_yaml_tpl = """
---
AWSTemplateFormatVersion: 2010-09-09
Resources:
ECRRepo:
Type: AWS::ECR::Repository
Properties:
RepositoryPolicyText:
Version: 3000-10-17 # <--- invalid version
Statement:
- Effect: Allow
Action:
- 'ecr:*'
Principal:
AWS: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:root
"""
default_events_limit = 10
@ -132,3 +149,79 @@ def test_missing_template_body():
assert exc_info.match('FAIL')
assert not m.exit_args
assert "Either 'template', 'template_body' or 'template_url' is required when the stack does not exist." == m.exit_kwargs['msg']
def test_disable_rollback_and_on_failure_defined():
m = FakeModule(
on_create_failure='DELETE',
disable_rollback=True,
)
with pytest.raises(Exception, message='Expected module to fail with both on_create_failure and disable_rollback defined') as exc_info:
cfn_module.create_stack(
module=m,
stack_params={'TemplateBody': ''},
cfn=None,
events_limit=default_events_limit
)
assert exc_info.match('FAIL')
assert not m.exit_args
assert "You can specify either 'on_create_failure' or 'disable_rollback', but not both." == m.exit_kwargs['msg']
def test_on_create_failure_delete(maybe_sleep, placeboify):
m = FakeModule(
on_create_failure='DELETE',
disable_rollback=False,
)
connection = placeboify.client('cloudformation')
params = {
'StackName': 'ansible-test-on-create-failure-delete',
'TemplateBody': failing_yaml_tpl
}
result = cfn_module.create_stack(m, params, connection, default_events_limit)
assert result['changed']
assert result['failed']
assert len(result['events']) > 1
# require that the final recorded stack state was DELETE_COMPLETE
# events are retrieved newest-first, so 0 is the latest
assert 'DELETE_COMPLETE' in result['events'][0]
def test_on_create_failure_rollback(maybe_sleep, placeboify):
m = FakeModule(
on_create_failure='ROLLBACK',
disable_rollback=False,
)
connection = placeboify.client('cloudformation')
params = {
'StackName': 'ansible-test-on-create-failure-rollback',
'TemplateBody': failing_yaml_tpl
}
result = cfn_module.create_stack(m, params, connection, default_events_limit)
assert result['changed']
assert result['failed']
assert len(result['events']) > 1
# require that the final recorded stack state was ROLLBACK_COMPLETE
# events are retrieved newest-first, so 0 is the latest
assert 'ROLLBACK_COMPLETE' in result['events'][0]
connection.delete_stack(StackName=params['StackName'])
def test_on_create_failure_do_nothing(maybe_sleep, placeboify):
m = FakeModule(
on_create_failure='DO_NOTHING',
disable_rollback=False,
)
connection = placeboify.client('cloudformation')
params = {
'StackName': 'ansible-test-on-create-failure-do-nothing',
'TemplateBody': failing_yaml_tpl
}
result = cfn_module.create_stack(m, params, connection, default_events_limit)
assert result['changed']
assert result['failed']
assert len(result['events']) > 1
# require that the final recorded stack state was CREATE_FAILED
# events are retrieved newest-first, so 0 is the latest
assert 'CREATE_FAILED' in result['events'][0]
connection.delete_stack(StackName=params['StackName'])

Loading…
Cancel
Save