AWS CFT Glue add sampling in DynamoDB Target - amazon-web-services

I have so far Glue Crawler defined in Cloud Formation Template as:
Type: AWS::Glue::Crawler
Properties:
Name: CrawlerName
DatabaseName: DBName
Targets:
DynamoDBTargets:
- Path: DynamoDBTableName
How I can turn on enable sampling option available in UI Console, but I do not see it in AWS Documentation of CFT

I haven't tried this myself, but this might work based on how the aws api for glue is structured
Type: AWS::Glue::Crawler
Properties:
Name: CrawlerName
DatabaseName: DBName
Targets:
DynamoDBTargets:
- Path: DynamoDBTableName
- ScanAll: False

Given that the default is to enable sampling you shouldn't have to add anything to the CFN template. I did try "ScanAll: True" to try and disable sampling but the command doesn't seem to be supported.
Property validation failure: [Encountered unsupported properties in {/Targets/DynamoDBTargets/1}: [ScanAll]]

Related

Customize Partner Event Source name in AWS CloudFormation script

I want to define the AppFlow configuration in a SAM template.
I don't want to let AWS automatically generate a Partner Event Source name like aws.partner/appflow/salesforce.com/${AWS::AccountId}/resource
It is possible to specify a custom name when setting up AppFlow manually via console (see step 4 in Amazon EventBridge.
I cannot find the right keyword to specify the name in CloudFormation (I guess it should go somewhere under AWS::AppFlow::Flow but the solution eludes me.)
TIA
The solution is to set AppFlow::Flow:DestinationFlowConfigList::DestinationConnectorProperties:EventBridge:Object to the suffix you want the source to have!
E.g.:
SalesforceAppFlow:
[...]
Type: AWS::AppFlow::Flow
Properties:
[...]
DestinationFlowConfigList:
- ConnectorType: "EventBridge"
DestinationConnectorProperties:
EventBridge:
Object: THIS_SUFFIX
[...]
PartnerEventBus:
Type: AWS::Events::EventBus
Properties:
Name: !Sub "aws.partner/appflow/salesforce.com/${AWS::AccountId}/THIS_SUFFIX"
EventSourceName: !Sub "aws.partner/appflow/salesforce.com/${AWS::AccountId}/THIS_SUFFIX"
DependsOn: SalesforceAppFlow
[...]

Dynamically change event properties on aws cloudformation templates

We are building a serverless app using aws and we want to enable lambda warmers only on the production environment.
Our cloudformation parameters:
Parameters:
Environment:
Description: Environment name
Type: String
EnableWarmer:
Description: Flag to enable/disable warmup Events
Default: DISABLED
Type: String
Our lambdas yaml file looks like this:
MyLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub '${Environment}-my-lambda'
CodeUri: src
Handler: lambda.handler
Runtime: nodejs12.x
MemorySize: 128
Timeout: 100
Description: Creates a new something
Layers:
- !Ref InternalDependencyLayer
- !Ref ExternalDependencyLayer
Role: !Ref LambdaRoleArn
Events:
Api:
Type: Api
Properties:
Path: /url
Method: POST
RestApiId: !Ref ApiGateway
WarmingSchedule:
Type: Schedule
Properties:
Enabled: !Ref EnableWarmer
Schedule: rate(5 minutes)
Input: '{ "warmer":true, "concurrency": 2 }'
And then we deploy the dev environment with these params:
- Key: Environment
Value: dev
- Key: EnableWarmer
Value: DISABLED
Similarly for the production environment we deploy with these params:
- Key: Environment
Value: production
- Key: EnableWarmer
Value: ENABLED
According to aws documentation parameters can't be of type boolean which is the required type of the enabled attribute of the schedule event.
Fortunately amazon states:
Enabled Indicates whether the rule is enabled.
To disable the rule, set this property to False.
Type: Boolean
Required: No
AWS CloudFormation compatibility: This property is similar to the
State property of an AWS::Events::Rule resource. If this property is
set to True then AWS SAM passes ENABLED, otherwise it passes DISABLED
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-schedule.html
However when we deploy to the dev environment the warmers are enabled.
The problem with the Enabled property here seems to be that it does not support using CloudFormation's If function and a Condition to do something like that:
WarmingSchedule:
Enabled: !If [WarmerCondition, true, false]
(At least I couldn't figure it out, but maybe I just did something wrong) This is similar to what #raul-barreto suggests with !Equals. However, in my tests it always sets the rule's status to ENABLED.
It seems like there are two options left what you can do:
a) (Not recommended) Copy the CloudFormation code of your Lambda function and have a second one available in your CloudFormation resources. Now set a condition to both of them so you only create one of them, depending on your environment. Note: I don't say this is a good approach but it'd be possible. Problems are you have to maintain the definition of both Lambda functions and if you repeat this approach, you'll faster reach CloudFormations template size limits.
b) If you want to make sure you have a minimum number of instances available to your function (at least that's what I interpret from your question), consider using AWS Lambda's Provisioned Concurrency feature instead. You can define it like this in your AWS Lambda function using SAM:
MyLambda:
Type: AWS::Serverless::Function
Properties:
AutoPublishAlias: 'LATEST' #Setting AutoPublishAlias is important, otherwise you can not use provisioned concurrency
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: 2
This snippet will provision concurrency for the function's alias 'LATEST' which points to the latest version of your function. Read more about AutoPublishAlias in SAM (Note: the link's content is written in the context of traffic shifting but it explains what the property does). It makes sure that you always have 2 instances of your Lambda functions available.
The accepted solution works, but as stated in comments, it is a bit difficult to control the enabling and disabling of the event. The following seems to work in a more robust way.
Events:
Scheduler:
Type: Schedule
Properties:
Schedule: !If [EnableWarmer, "rate(5 minutes)",
"cron(00 00 01 01 ? 1970)"]
According to the documentation, Enabled must a Boolean variable.
You can still have a String parameter and convert it to Boolean inside the CloudFormation.
WarmingSchedule:
Type: Schedule
Properties:
Enabled: !Equals [!Ref EnableWarmer, ENABLED]
Schedule: rate(5 minutes)
Input: '{ "warmer":true, "concurrency": 2 }'
This way you still can send ENABLED or DISABLED as a parameter but the input of WarmingSchedule.Enabled will be a Boolean.

AWS Athena deployment serverless framework

has somebody a hint how I have to transform !Ref und !Sub from CloudFormation into serverless.yml.
resources:
Resources:
AthenaCreateDatabaseQuery:
Type: 'AWS::Athena::NamedQuery'
Properties:
Description: Run this query to initialize the Athena database
QueryString: "CREATE DATABASE IF NOT EXISTS $(self:custom.etlDatabase};"
Database: ${self:custom.etlDataBase}
In Cloudformation the QueryString Property starts with !Sub and
the Database Property with !Ref.
Thanks Christian
!Sub isn't currently supported natively by serverless.com (see this issue on GitHub) but you can use the following plugin https://gitlab.com/kabo/serverless-cf-vars
Whenever you want the cloudformation template to have a string that contains ${}, simply use #{} instead, and it will get transformed into correct ${} (with Fn::Sub inserted for you) in the cloudformation template before deployment.
Or use a custom variable syntax as suggested here. Both require the use of Fn::Sub and Fn::Ref in yaml instead of the short form !Sub and !Ref

How To Rollback AWS CodeStar Lambda Functions Deployed Via CloudFormation?

I'm creating a Nodejs microservice for AWS Lambda. I scaffolded by project using AWS Codestar, and that set me up with a CI/CD pipeline that automatically deploys the lambda function. Nice.
The issue is that every time it deploys the lambda function it must delete and recreate the function, thus deleting any versions or aliases I made.
This means I really can't roll back to other releases. I basically have use git to actually revert the project, push to git, wait for the super-slow AWS Code Pipeline to flow through successfully, and then have it remake the function. To me that sounds like a pretty bad DR strategy, and I would think the right way to rollback should be simple and fast.
Unfortunately, it looks like the CloudFormation section of AWS doesn't offer any help here. When you drill into your stack on the first CloudFormation page it only shows you information about the latest formation that occurred. Dear engineers of AWS CloudFormation: if there was a page for each stack that showed a history of CloudFormation for this stack and an option to rollback to it, that would be really awesome. For now, though, there's not. There's just information about the latest formation that's been clouded. One initially promising option was "Rollback Triggers", but this is actually just something totally different that lets you send a SNS notification if your build doesn't pass.
When I try to change the CodePipeline stage for deploy from CREATE_CHANGE_SET to CREATE_UPDATE I then get this error when it tries to execute:
Action execution failed UpdateStack cannot be used with templates
containing Transforms. (Service: AmazonCloudFormation; Status Code:
400; Error Code: ValidationError; Request ID:
bea5f687-470b-11e8-a616-c791ebf3e8e1)
My template.yml looks like this by the way:
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::CodeStar
Parameters:
ProjectId:
Type: String
Description: AWS CodeStar projectID used to associate new resources to team members
Resources:
HelloWorld:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs8.10
Environment:
Variables:
NODE_ENV: staging
Role:
Fn::ImportValue:
!Join ['-', [!Ref 'ProjectId', !Ref 'AWS::Region', 'LambdaTrustRole']]
Events:
GetEvent:
Type: Api
Properties:
Path: /
Method: get
PostEvent:
Type: Api
Properties:
Path: /
Method: post
The only options in the CodePipeline "Deploy" action are these:
It would be really great if someone could help me to see how in AWS you can make Lambda functions with CodePipeline in a way that they are easy and fast to rollback. Thanks!

AWS Get API Gateway URL for Use in Cloud Formation

I'm looking to use CloudFormation to build my AWS stack which includes an API Gateway with Usage Plans. I'd like to specify my usage plans in my main CloudFormation template, rather than having to add them as a change-set after the initial stack create. The problem is that the stack fails to create when I include the usage plan because (I think) the API Gateway is not finished deploying when it tries to create the usage plans since I get an error saying that the stage "prod" does not exist. My CloudFormation template (extract) looks like this:
Api:
Properties:
CacheClusterEnabled: true
CacheClusterSize: '0.5'
DefinitionUri: {MYS3URL}
StageName: prod
Type: AWS::Serverless::Api
ApiFreeUsagePlan:
DependsOn: Api
Properties:
ApiStages:
- ApiId:
Ref: Api
Stage: prod
Description: Free usage plan
UsagePlanName: Free
Type: AWS::ApiGateway::UsagePlan
I thought adding DependsOn: Api to the usage plan definition would work but it doesn't so I'm out of ideas?
It seems like my DependsOn statement should be on the ApiDeployment which I can see in the stack create events is still in progress when it tries to create the usage plan
The only way I've found that can do this is by setting the DependsOn property of the Usage plan to the logical Api Stage name which is {LogicalApiName}{StageName}Stage for example in my case:
Api:
Properties:
CacheClusterEnabled: true
CacheClusterSize: '0.5'
DefinitionUri: {MYS3URL}
StageName: prod
Type: AWS::Serverless::Api
ApiFreeUsagePlan:
DependsOn: ApiprodStage
I don't like this as it relies on the logical stage naming convention which I don't believe is officially documented in the AWS CloudFromation docs, however it appears to be the only reliable option