How to reference the --s3-bucket value in my Outputs? - amazon-web-services

I do a SAM deployment from my local console. With sam package ... --s3-bucket xy I specify the existing s3-bucket where deployment relevant objects are stored. I want that bucket to appear in the Output section in Cloudformation but I don't know how to reference it.
If I look under Template in the web console I see the path:
Resources:
MyLambda:
Properties:
CodeUri: s3://xy/1b26f7841...
So I tried to add
Outputs:
SourceBucket:
Value: !GetAtt MyLambda.Properties.CodeUri
to my template.yaml, but the deployment fails with Requested attribute Properties.CodeUri does not exist in schema for AWS::Lambda::Function

Sadly you can't do this. AWS::Serverless::Function does not return such information. You would have to use custom resource to get it.
Alternatively, if you pass the bucket uri as input parameter to your template, you can output the parameter's value directly.

Related

How to get the ssm parameter to a yaml file?

I have a yaml cloud formation file which requires a variable stored in ssm parameter. The yaml file is a CFT template. Below is the sample code,
AWSTemplateFormatVersion: 2010-09-09
Description: 'Fully Automated OT Archival Data Migration'
Parameters:
Environment:
Description: 'Stage type (for Tags)'
Type: String
Default: dev
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: '{{resolve:ssm:/opentext/config/automated-ot-archival-data-migration/migration.bucket.name:1}}-${Environment}'
When I upload the code to cloudformation in AWS console, I results with an error. I'm wondering whether the ssm param reference is correct or not.
Please let me know if you find any issues here.
Thanks
You are missing the !Sub function for your {Environment} variable.
BucketName: !Sub '{{resolve:ssm:/opentext/config/automated-ot-archival-data-migration/migration.bucket.name:1}}-${Environment}'

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

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

Dynamically create resource names in AWS SAM using parameters

I want to dynamically create names for my resources in my Cloud Formation stack when using AWS SAM if this is possible.
E.g. when I package or deploy I want to be able to add soemthing to the command line like this:
sam package --s3-bucket..... --parameters stage=prod
When in my template.yml file somehow to do something like this:
Resources:
OrdersApi:
Type: AWS::Serverless::Function
Properties:
FunctionName: orders-api-${stage}
CodeUri: ./src/api/services/orders/
...
Note for the OrdersApi property of FunctionName I want to dynamically set it to orders-api-prod which is the value I attempted to pass in on the CLI.
I can do this quite easily using the Serverless Framework but I can't quite work out how to do it with SAM.
You can use functions like Sub to construct resource names in CloudFormation. Something along the lines:
Parameters:
stage:
Type: String
Default: dev
AllowedValues:
- dev
- prod
Resources:
OrdersApi:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub 'orders-api-${stage}'
The answer posted by lexicore is correct and you can form values in certain parts of the template.yaml file using the !Sub function e.g.
FunctionName: !Sub 'orders-api-${stage}'
The missing part of why this wouldn't work is that you need to pass the parameters through to the sam deploy command in a specific format. From reading the AWS docs, sam deployis shorthand for aws cloudformation deploy.... That command allows you to pass parameters using the following syntax:
aws cloudformation deploy .... --parameter-overrides stage=dev
This syntax can also be used with the sam deploy command e.g.
sam deploy --template-file packaged.yml ..... --parameter-overrides stage=dev
Note that in this example stage=dev applies to the Parameters section of the template.yaml file e.g.
Parameters:
stage:
Type: String
AllowedValues:
- dev
- stage
- prod
This approach allowed me to pass in parameters and dynamically change values as the cloud formation stack was deployed.

How to specfiy existing FunctionName on SAM Template

I'm trying to deploy AWS Lambda function by using SAM.
What I want to do is to update exsiting lambda function by deploying local source code.
In order to do that, I specified the existing lambda function name as 'FunctionName' in template.yaml like below.
However, 'FunctionName' does only support for creating new function, not updating to existing function.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-functionname
Are there any ways to specify Function Name in SAM in order to update lambda function?
[template.yaml]
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
HelloWorld:
Type: 'AWS::Serverless::Function'
Properties:
FunctionName: 'hello_world'
Description: ''
Handler: index.handler
MemorySize: 256
Role: 'arn:aws:iam::368834739507:role/lambda_basic_execution'
Runtime: nodejs6.10
Timeout: 120
Using SAM (and/or CloudFormation), you cannot update existing resources.
SAM (and CloudFormation) create and manage their own resources. All resources specified in the template are going to be created when the stack is created. They cannot be "taken over".
Instead, you should allow SAM (or CloudFormation) to create the Lambda function for you, then update users to reference the new function. After that, you can update your code using SAM.