AWS Athena deployment serverless framework - amazon-web-services

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

Related

AWS CFT Glue add sampling in DynamoDB Target

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

Finding AWS KMS ID by alias in CloudFormation

I'm creating a AWS::Timestream::Database service and I want to use one of our KMS keys that's been created externally of the CloudFormation template.
I want to use the alias of the key, but I can't find any good way to get the reference of the key into the template.
I've found some references to use !Sub to be able to get the ARN, but how to get ID from there?
I have used the following code in my S3 cross account replication CF template for collecting the KMS alias. You can try the same approach.
ReplicaKmsKeyID: !Join ['',['arn:aws:kms:', !Ref BucketRegion, ':', !Ref AWS::AccountId, ':alias/aws/s3']]
#ReplicaKmsKeyID: arn:aws:kms:us-west-2:111111111111:alias/aws/s3
You can use alias with your kms id like arn:<partition>:kms:<region>:<account-id>:alias/<alias-name>
AWSTemplateFormatVersion: 2010-09-09
Resources:
DB:
Type: AWS::Timestream::Database
Properties:
DatabaseName: <DB_NAME>
KmsKeyId: arn:aws:kms:<REGION>:<ACCOUNT_ID>:alias/<ALIAS>

How to pass parameters to a cloudformation template which is embedded inside serverless.yaml file

I have a cloudformation template that I would like to embed in the resources section but the existing cloudformation template contains parameters. Is it possible to handle this?
resources: Resources: ${file(cloudformation-resources.yaml)}
I am trying to create IAM roles and Lambda functions using the template. and the template takes the environment name, security groupId, bucket name where the lambda code resides as passing as parameters. and I am using !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/ to get the log group inside the template.
But I am ending up with an error " Invalid variable reference syntax for variable AWS::Region. You can only reference env vars, options, & files. You can check our docs for more info."
How can I handle this using serverless.yaml file.
Here is the serverless.yaml which i am trying
service: sample
frameworkVersion: ">=1.0.0 <2.0.0"
plugins:
- serverless-pseudo-parameters
provider:
name: aws
stackName: "${opt:stackName,env:StackName}"
parameters:
SecurityGroupId: "${opt:SecurityGroupId,env:SecurityGroupId}"
Subnets: "${opt:Subnets,env:Subnets}"
environment: "${opt:environment,env:environment}"
LambdacodeBucketName: "${opt:LambdacodeBucketName,env:LambdacodeBucketName}"
resources:
- ${file(test/template.yaml)}
Thanks in advance

DependsOn with if else statement in cloudforamtion yml template

Hi i have 2 AWS::ElasticLoadBalancingV2::Listener name Listener1 and Listener2. I have a condition in which either listner1 is deployed or listner1
I have created a ecs service which i want to be depended on Listener.
Service:
Type: AWS::ECS::Service
DependsOn: !If [Condition, Listener1, Listener2]
Properties:
When deployed its giving me error Template format error: DependsOn must be a string or list of strings.
Sadly, you can't do the following:
DependsOn: !If [Condition, Listener1, Listener2]
As the error message says, DependsOn takes only a string value or a list of strings, not a function, e.g:
DependsOn: [SomeExistingResource1, SomeExistingResource2]
Also Fn::If can only be used in metadata attribute, update policy attribute, and property values. From docs:
Currently, AWS CloudFormation supports the Fn::If intrinsic function in the metadata attribute, update policy attribute, and property values in the Resources section and Outputs sections of a template.
Thus you can't use Fn::If in DependsOn.

AWS SAM: can we use a already existing api in aws sam template?

I have a lambda function that needs to be triggered via Amazon API Gateway. Is there a way to include an already existing API (created using the AWS console) into AWS SAM template?
SAM doesn't support the !ImportValue in the template yet.
Issue on Github
On the GitHub of the aws/serverless-application-model there's an open PR for that feature
See here
If you want you could help and contribute to that PR so then you could start using !ImportValue in your SAM template.yml
Else, I suggest you go with the old way, you create a CI/CD with a CloudFormation template that can use the !ImportValue and is linked to an S3 bucket where your lambda function code lives.
Examples of Cloudformation Templates
Update
SAM CLI now support the !ImportValue, the issue on Github is closed.
You can use it as follow
# You need to export the resource that you want to use in another template first
# This goes at the end of your template.yml file, after the Resources
# template.yml in the first repo
Outputs:
myExportedResource:
Value: !Ref TheResource
Export:
Name: !Sub "{environment}-nice-export-name"
# template.yml in the second repo (This obviously goes in Resources)
MyLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: awesome-lambda
CodeUri: ./dist
Handler: this-file.handler
Role: !GetAtt LambdaRole.Arn
VpcConfig:
SecurityGroupIds:
- !GetAtt SecurityGroup.GroupId
SubnetIds:
- Fn::ImportValue: !Sub "${environment}-nice-export-name"
You can use it exactly as a normal cloudformation template
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html
Note that here I used Fn:ImportValue because I needed to use !Sub but if you don't need to reference a parameter in your import value simply use !ImportValue