In order to solve issues such as throttling (#588) or other scenarios where you want to delay the the next resource in line for deployment, I would like to propose to create a new CloudFormation resource type. It should be very similar to AWS::CloudFormation::WaitCondition[1], except that we don't need to wait for an external process, only for a period of time.
A property should be available to receive the timeout. The value must be in ISO8601 duration format [2], in the form: PT#H#M#S, where each # is the number of hours, minutes, and seconds, respectively.
SUCCESS after the amount of time specified by user has passed.This is an example usage for this hypothetical resource type:
DomainName1:
Type: AWS::ApiGateway::DomainName
Properties:
DomainName: example.com
CertificateArn: ...
Delay:
Type: AWS::CloudFormation::Delay
Properties:
Timeout: PT1M
# This should only start after 1 minute has passed
DomainName2:
Type: AWS::ApiGateway::DomainName
DependsOn: Delay
Properties:
DomainName: api.example.com
CertificateArn: ...
Was able to work on something similar :) Hope it helps -
Resources:
domainName1:
Type: 'AWS::ApiGateway::DomainName'
Properties:
DomainName: k.badaldavda.xyz
CertificateArn: >-
arn:aws:acm:us-east-1:xxx:certificate/103217f9-884b-4d6d-9ac6-ba7500e61029
domainName2:
DependsOn: Delay2
Type: 'AWS::ApiGateway::DomainName'
Properties:
DomainName: l.badaldavda.xyz
CertificateArn: >-
arn:aws:acm:us-east-1:xxx:certificate/103217f9-884b-4d6d-9ac6-ba7500e61029
domainName3:
DependsOn: Delay3
Type: 'AWS::ApiGateway::DomainName'
Properties:
DomainName: m.badaldavda.xyz
CertificateArn: >-
arn:aws:acm:us-east-1:xxx:certificate/103217f9-884b-4d6d-9ac6-ba7500e61029
Delay2:
Type: 'Custom::Delay'
Properties:
ServiceToken: !GetAtt DelayFunction.Arn
TimeToWait: 60
domainName: !Ref domainName1
Delay3:
Type: 'Custom::Delay'
Properties:
ServiceToken: !GetAtt DelayFunction.Arn
TimeToWait: 60
domainName: !Ref domainName2
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: "lambda-logs"
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- "arn:aws:logs:*:*:*"
DelayFunction:
Type: 'AWS::Lambda::Function'
Properties:
Handler: "index.handler"
Timeout: 120
Role: !GetAtt 'LambdaRole.Arn'
Runtime: python3.7
Code:
ZipFile: |
import json
import cfnresponse
import time
def handler(event, context):
time_to_wait = int(event['ResourceProperties']['TimeToWait'])
print('wait started')
time.sleep(time_to_wait)
responseData = {}
responseData['Data'] = "wait complete"
print("wait completed")
physicalId = event['ResourceProperties']['domainName'] + 'wait'
print(physicalId)
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, physicalId)
Following the proposal, a new private resource type Community::CloudFormation::Delay has been released in the meantime.
Installation instructions:
aws cloudformation register-type \
--region us-east-1 \
--type-name "Community::CloudFormation::Delay" \
--schema-handler-package "s3://community-resource-provider-catalog/community-cloudformation-delay-0.1.0.zip" \
--type RESOURCE
Usage example:
AWSTemplateFormatVersion: 2010-09-09
Resources:
Delay:
Type: Community::CloudFormation::Delay
Properties:
Duration: PT30S
@eduardomourar is it possible to use with CDK?
Partially, because you cannot register the type using CDK yet. But, after registering in some other way, you can deploy a Delay by leveraging cdk.CfnResource directly (details here).
Following the proposal, a new private resource type
Community::CloudFormation::Delayhas been released in the meantime.Installation instructions:
aws cloudformation register-type \ --region us-east-1 \ --type-name "Community::CloudFormation::Delay" \ --schema-handler-package "s3://community-resource-provider-catalog/community-cloudformation-delay-0.1.0.zip" \ --type RESOURCEUsage example:
AWSTemplateFormatVersion: 2010-09-09 Resources: Delay: Type: Community::CloudFormation::Delay Properties: Duration: PT30S
I registered this resource in my environment in region eu-central-1, when I try to run this from stacksets I receive an error message "Template format error: Unrecognized resource types: [Community::CloudFormation::Delay]"
Following the proposal, a new private resource type
Community::CloudFormation::Delayhas been released in the meantime.
Installation instructions:aws cloudformation register-type \ --region us-east-1 \ --type-name "Community::CloudFormation::Delay" \ --schema-handler-package "s3://community-resource-provider-catalog/community-cloudformation-delay-0.1.0.zip" \ --type RESOURCEUsage example:
AWSTemplateFormatVersion: 2010-09-09 Resources: Delay: Type: Community::CloudFormation::Delay Properties: Duration: PT30SI registered this resource in my environment in region eu-central-1, when I try to run this from stacksets I receive an error message "Template format error: Unrecognized resource types: [Community::CloudFormation::Delay]"
Oh wait I got it, I would need to register that in all accounts I want to use this delay right? so this is a NOGO for deployment through organization... would be nice to have a real resource -> AWS::CloudFormation::Delay
yes, you need to register the delay resource in every account and region you plan to use it
@eduardomourar do you have a ETA for the official new resource type Delay?
I don't work for AWS, so @luiseduardocolon is this in the short-term plans?
This works great, thanks so much for this resource type. I find it a bit strange that AWS doesn't provide this out of the box.
One suggestion for improving this further: specify properties to instruct CF whether to run the delay for each of the build operations (Create, Update, Delete). I foresee scenarios where the delay is needed for Create / Delete but not Update, so it would be nice to have control over this.
@eduardomourar I found that the delay only happens the first time, and doesn't happen on subsequent stack updates. Looking at the events, CloudFormation only creates the resource the first time, and skips it afterwards.
I think you can work around this issue if you add a property such as Timestamp and pass it into the resource with a different value on each run.
Most helpful comment
Following the proposal, a new private resource type
Community::CloudFormation::Delayhas been released in the meantime.Installation instructions:
Usage example: