AWS CloudFormation pseudo parameters are incorrect locally - amazon-web-services

I am working on AWS Serverless application using SAM. My template.yaml has this line for defining an S3 bucket name:
BucketName: !Sub ${AWS::StackName}-visit-attachments-${AWS::AccountID}
When I deploy to AWS using sam deploy the variables are substituted correctly.
But when I execute the lambda function locally, the resulting string is local-visit-attachments-123456789012. I can't find where the local and 123456789012 are coming from since I don't have them anywhere in the configs.
How can I make it so it uses the same values locally as when I deploy to AWS?

sam local invoke takes --env-vars parameter. You should be able to overwrite these default values by setting AWS_REGION and AWS_ACCOUNT_ID.

Related

Get updated AWS Lambda URL after deployment

I have set up CI/CD for an AWS Lambda function such that the new version is automatically deployed using GitHub actions. By default, AWS creates a new Lambda ID (and thus URL) for this lambda function. This means that the front-end portion of my code will need to be updated to contain the updated URL. Is there a way to automatically perform such updating? By e.g. saving the URL as an environment variable and inserting it in the code with a GitHub action?
Or is there alternatively a way to re-use the old Lambda function URL for new deployments?
You can get the updated Lambda URL by using SAM template outputs as follows:
Resources:
MyFunction:
Type: 'AWS::Serverless::Function'
Outputs:
MyFunctionUrlEndpoint:
Description: "My Lambda Function URL Endpoint"
Value: !GetAtt MyFunctionUrl.FunctionUrl
Then you can access the output as described in this answer:
aws cloudformation describe-stacks --stack-name stack_name --query 'Stacks[0].Outputs[?OutputKey==`MyFunctionUrlEndpoint`].OutputValue' --output text
which can then be further processed in e.g. your front-end code.
There may be easier methods, but this should work!

Does AWS sam cli print template.yaml config file with all variables resolved

I have switched from serverless to sam cli. One useful function serverless had was serverless print which allowed you to print the output of your yaml file with all the local variables resolved. This was a useful tool for checking if your syntax is correct or if the variables are resolving as you expect.
Is that any way to do this with AWS sam cli?
e.g.
sam print
You can achieve this using Outputs section of SAM template.
You can check the AWS SAM template anatomy to understand better.
Outputs (optional)
The values that are returned whenever you view your stack's properties. For example, you can declare an output for an S3 bucket
name, and then call the aws cloudformation describe-stacks AWS Command
Line Interface (AWS CLI) command to view the name. This section corresponds directly with the Outputs section of AWS CloudFormation templates.
You will need to make use of Intrinsic functions within your Outputs section to print out the final resolved value at runtime.
Outputs:
BackupLoadBalancerDNSName:
Description: The DNSName of the backup load balancer
Value: !GetAtt BackupLoadBalancer.DNSName
Condition: CreateProdResources
InstanceID:
Description: The Instance ID
Value: !Ref EC2Instance
If you just wish to validate if your SAM is correct or not you could use the following command:
$ sam validate
Posting the answer here so that it may help others in future!

Both SAM and cdk can make stack, SAM include cdk ? or cdk include SAM?

I want to make two bucket(x,y) in S3 and make a lambda.
My goal is uploading files to S3(x) and it triggers lambda then lambda create and put file in S3(y)
Currently, I am developing lambda function on SAM.
Deploying lambda function by SAM
And I made two S3 buckets by cdk.
Then manually adding trigger and Iam policy to lambda to access S3
However I want to do this all automatically.
So my idea is ,
SAM can make two S3 bucket as stack and I don't need cdk anymore ?
cdk can include SAM development environment?
Any other way??
What is the best practice for this purpose??
My `solution is
Local development with SAM
AWS deployment is carried out by cdk only, SAM doesn't work anything for deployment.
My folder structure is below
cdk / bin
lib
cdk.json
etc
samproj/helloworld/app.py
/samconfig.toml
/template.yaml
/etc
For local developing, in samproj directory, do something like this, tutorial.
sam local invoke "HelloWorldFunction" -e events/event.json
And for AWS deployment by cdk project .
Just make lambda directly from samproj/helloworld directory in Stack.
export class CdkVrBaseStack extends Stack {
const lambda_ = new lambda.Function(this, 'TestLambda', {
functionName: 'testLambda',
runtime: lambda.Runtime.PYTHON_3_9,
code: lambda.Code.fromAsset('samproj/helloworld'),
handler: 'index.handler',
timeout: cdk.Duration.seconds(300),

AWS SAM update function code of lambda of an API Gateway

I am using CloudFormation with SAM to deploy a stack which contains:
S3 Bucket
Cognito
AWS::Serverless::Api
AWS::Serverless::Function (authorizers + microservices, Type: Api and endpoints of the API Gateway)
Log Groups
To deploy my stack, I first run aws cloudformation package to package the lambda and then run aws cloudformation deploy to deploy the generated stack. This is working.
My goal now is to be able to update a microservice without deploying the entire stack (not building authorizers and other microservices), similar to serverless deploy function in the Serverless framework. This should preferably be one reusable template that uses a macro or just replaces text in the file.
The problem I am facing with this:
Running aws lambda update-function-code requires the lambda to be redeployed
To redeploy the lambda I have to declare AWS::Serverless::Function. For the function to be part of the API Gateway, AWS::Serverless::Api must be declared as well.
Declaring AWS::Serverless::Api requires all the other functions to be defined or they will be removed from the API Gateway.
I feel like I am stuck here and have not found other options of achieving my goal.
Since you're using SAM, I'd recommend deploying and updating your application using the sam cli commands.
You can run
sam build
sam package
sam deploy
When you run sam deploy, it deploys your application, but all subsequent sam deploy commands will update your existing cloudformation stack with only the appropriate resources that need updating.
If you opt for keeping with the standard Cloudformation cli commands, you could use the aws cloudformation update-stack command so that you're not re-deploying an entire new stack.

How to deploy environment variable using serverless deploy for AWS lambda

I am new to AWS lambda i have i am using serveless deploy to deploy my lambda function declared in serverless.yml file.
In that file i wrote a lambda function i deployed and it is working fine but problem is that whatever environment variable i gave is not available in console of that lambda function. I might be doing some minor mistake or for deploying environment variable there should be some other syntax.
I can go to lambda function in console and add environment variable manually.
But my doubt is can we do it while deploying it through serverless deploy
You can use versions and aliases provided by AWS Lambda
You can create different versions of the same lambda function and give them an alias. Like when you push your lambda code - create a version (say it's 5) - create an alias this (say TEST).
When you're sure that its ready for production, create a version(or choose an existing version and name that (say PROD).
Now whenever your lambda function executes, it gives lambda ARN
which contains alias, by that you can know which alias(in context.invokedFunctionArn) is
executed i.e. that can be used as the environment variable. While
invoking the function, you can mention which function to execute from
your invocation code.
let thisARN = context.invokedFunctionArn;
// Get the last string in ARN - It's either function name or the alias name
let thisAlias = thisARN.split(":").pop();
Now whenever you deploy a new code, just point the alias to that version.
You can use AWS console or CLI for that.
Take a look at this lambda versioning and aliases
For directly deploying to your alias(PROD), you can do this -
aws lambda update-alias \
--region region \
--function-name helloworld \
--function-version 2 \
--name PROD
serverless deploy
Serverless deploy works fine for deployment on any stage it also deploys environment variable in given stage, my case environment variable was not deployed of indentation problem in yaml file, and even serverless deploy command was not throwing error it was deploying function but environment variables were not deployed
In yaml file we can state the the stage where we want to deploy like this
provider:
name: aws
runtime: nodejs6.10
stage: dev
region: eu-west-2
Hope this will help if someone gets similar issue