cloudformation-coverage-roadmap icon indicating copy to clipboard operation
cloudformation-coverage-roadmap copied to clipboard

AWS::CloudFormation::Delay (new resource)

Open eduardomourar opened this issue 3 years ago • 17 comments

1. Title

AWS::CloudFormation::Delay (new resource)

2. Scope of request

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.

3. Expected behavior

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.

In Create/Update/Delete, it should return SUCCESS after the amount of time specified by user has passed.

4. Suggest specific test cases

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: ...

5. Helpful Links to speed up research and evaluation

[1]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-waitcondition.html

[2]: http://en.wikipedia.org/wiki/ISO_8601#Durations

6. Category

  1. Management (CloudTrail, Config...)

eduardomourar avatar Aug 03 '20 23:08 eduardomourar

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)

badaldavda8 avatar Aug 07 '20 17:08 badaldavda8

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 avatar Aug 09 '20 23:08 eduardomourar

@eduardomourar is it possible to use with CDK?

jdiegosierra avatar Nov 11 '20 11:11 jdiegosierra

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).

eduardomourar avatar Nov 12 '20 17:11 eduardomourar

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

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]"

githubnoobieme avatar Dec 04 '20 08:12 githubnoobieme

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

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]"

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

githubnoobieme avatar Dec 04 '20 09:12 githubnoobieme

yes, you need to register the delay resource in every account and region you plan to use it

eduardomourar avatar Dec 04 '20 09:12 eduardomourar

@eduardomourar do you have a ETA for the official new resource type Delay?

githubnoobieme avatar Dec 04 '20 09:12 githubnoobieme

I don't work for AWS, so @luiseduardocolon is this in the short-term plans?

eduardomourar avatar Dec 04 '20 09:12 eduardomourar

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.

dobomode avatar Dec 28 '20 12:12 dobomode

@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.

petrgazarov avatar Jan 08 '21 03:01 petrgazarov

much needed. @eduardomourar your workaround helps!

nbrational avatar Jul 02 '21 03:07 nbrational

I feel like this is not a great fix for throttling issue in API gateway. AWS service like Cloudformation should be aware of throttling limits of other AWS services it creates resources in. Or any 429 error shouldn't cause creation to fail, since it has very specific meaning and default action should be wait and retry

TomasChmelik avatar Nov 02 '21 12:11 TomasChmelik

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 Any chance you would be willing to contribute this to the new registry extension repo? I created an issue there for this exact thing before I realized we already had a request for it here: https://github.com/aws-cloudformation/community-registry-extensions/issues/80

ericzbeard avatar Nov 04 '22 17:11 ericzbeard

The source code written in TypeScript is already available here (https://github.com/org-formation/aws-resource-providers/tree/master/cloud-formation/delay). If that helps, I am happy to create PR copying the code as is to your repository.

eduardomourar avatar Nov 04 '22 20:11 eduardomourar

is this implemented yet?

AlHanouf-BH avatar Aug 09 '23 18:08 AlHanouf-BH

Any update on this?

mdeguzis avatar Feb 16 '24 17:02 mdeguzis