Error when calling LambdaInvoke in aws CDK stepfunction - amazon-web-services

I am trying to create a stepfunction via AWS CDK.
The stepfunctions should, among other things, call a lambda function.
I am using the lambdaInvoke task as described in: https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_stepfunctions_tasks/LambdaInvoke.html
For the lambda_function parameter I am trying to use an existing Lambda by referencing its ARN using
https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_lambda/Function.html#aws_cdk.aws_lambda.Function.from_function_arn
(i tried using from_function_attributes as well)
My cdk code looks like this
lambda_name = sfn.Task(
self, "Lambda Name",
task=sfn_tasks.LambdaInvoke(self, "lambdaInvoke",lambda_function=lambda_.Function.from_function_arn(self,"import-lambda",function_arn="arn:aws:lambda:eu-west-1:accountnumber:function:LambdaName")),
result_path="$.guid"
)
I am trying to call an existing lambda. (the lambda itself is created and updated in a pipeline setup in the same CDK project, but in a different stack)
I also tried adding :%LATEST to LambdaName, and both give me the same error:
jsii.errors.JSIIError: props.task.bind is not a function
I made a support ticket for the issue, they ran into the same issue and referred me to here.
How do I invoke a lambda via cdk?
Update:
LambdaInvoke is not supposed to be imbedded in a task.
lambda_name = sfn_tasks.LambdaInvoke(
self, "lambdaInvoke",
lambda_function=lambda_.Function.from_function_arn(self,"import-lambda",function_arn="arn:aws:lambda:eu-west-1:accountnumber:function:LambdaName")),
result_path="$.guid"
)
Works

Related

Terraform handle multiple lambda functions

I have a requirement for creating aws lambda functions dynamically basis some input parameters like name, docker image etc.
I have been able to build this using terraform (triggered using gitlab pipelines).
Now the problem is that for every unique name I want a new lambda function to be created/updated, i.e if I trigger the pipeline 5 times with 5 names then there should be 5 lambda functions, instead what I get is the older function being destroyed and a new one being created.
How do I achieve this?
I am using Resource: aws_lambda_function
Terraform code
resource "aws_lambda_function" "executable" {
function_name = var.RUNNER_NAME
image_uri = var.DOCKER_PATH
package_type = "Image"
role = role.arn
architectures = ["x86_64"]
}
I think there is a misunderstanding on how terraform works.
Terraform maps 1 resource to 1 item in state and the state file is used to manage all created resources.
The reason why your function keeps getting destroyed and recreated with the new values is because you have only 1 resource in your terraform configuration.
This is the correct and expected behavior from terraform.
Now, as mentioned by some people above, you could use "count or for_each" to add new lambda functions without deleting the previous ones, as long as you can keep track of the previous passed values (always adding the new values to the "list").
Or, if there is no need to keep track/state of the lambda functions you have created, terraform may not be the best solution to solve your needs. The result you are looking for can be easily implemented by python or even shell with aws cli commands.

Updating Lambda using CDK doesn't deploy latest image

Using the AWS C# CDK.
I get a docker image from an ECR repository & then create a lambda function using it.
The problem is that when I run the CDK, it clearly creates CloudFormation that updates the function. Within the AWS console, the latest image is then shown under "Image > Image URI". However the behaviour of my lambda clearly shows that the latest image has NOT been deployed.
If I click "Deploy New Image", leave everything as normal & click Save, my Lambda then shows that it is updating & then the behaviour of my lambda is as expected (latest image).
Unsure where I'm going wrong:
var dockerImageCode = DockerImageCode.FromEcr(ecrRepositoryContainingImage);
var dockerImageFunction = new DockerImageFunction(this,
Constants.LAMBDA_ID,
new DockerImageFunctionProps()
{
Code = dockerImageCode,
Description = versionString,
Vpc = foundationStackVpc,
SecurityGroups = new ISecurityGroup[]
{
securityStackVpcSecurityGroup
},
Timeout = Duration.Seconds(30),
MemorySize = 512
});
It is almost like, my lambda gets updated & shows that it is apparently pointing at the correct image within ECR. However the reality is, that it is not actually deployed.
Edit: A temporary fix is to ensure that rather than pushing a new image:latest image to ECR, I now call it image:buildnumber. It seems that even if the image in ECR is underlyingly different & cdk has supposedly updated the lambda image reference to the newly uploaded one in ECR, it doesn't actually redeploy/consider a change has occurred worthy of redeployment when the old image tag & new image tag are both named the same, in this case latest. Now since the build number will always be different & thus the new image tag will always be different to the previous one, this is deemed enough of a change for the lambda to be redeployed properly.
When using API fromEcr, you can specify EcrImageCodeProps with specified image tag.
See doc for detail.
The tag: latest did not work for me also. I think an easy way is to use SSM in the CodeBuild
'aws ssm put-parameter --name FhrEcrImageTagDemo --type String --value ${CODEBUILD_RESOLVED_SOURCE_VERSION} --overwrite'
Then in CDK lambda
code: aws_lambda.Code.fromEcrImage(
aws_ecr.Repository.fromRepositoryName(
this,
'id',
'ecrRepositoryName',
),
{
tag: aws_ssm.StringParameter.valueForStringParameter(
this,
'parameterName'
)
}
)
Another potential solution is using the exported variables and override parameters in this example class TagParameterContainerImage. It works for ecs but not sure for lambda and ecr.

AWS CDK create Lambda from image

I am a new to AWS world. I am working on a project to build a server less application and as part of that I have created 4 lambda which works fine.
Next I am trying to create a deployment pipe line using CDK; below is what I am trying to do.
create an docker image with code that includes all lambda code
create 4 different lambdas from same image just override the CMD in docker image and mention the lambda handler
I have setup CDK locally and able to create stack, everything works fine.
Below is my code snippet
--create the docker image
asset_img = aws_ecr_assets.DockerImageAsset(
self,
"test_image",
directory=os.path.join(os.getcwd(), "../mysrc")
)
--create lambda from docker image
aws_lambda.DockerImageFunction(
self,
function_name="gt_from_image",
code=_lambda.DockerImageCode.from_ecr(
self,
repository=asset_img.repository,
tag="latest")
)
Below is the error I am getting
TypeError: from_ecr() got multiple values for argument 'repository'
I am not sure how I can reference the image that was created and define the lambda.
Solved: Below is the solution
asset_img = _asset.DockerImageAsset(self, "test_image", directory=os.path.join(os.getcwd(), "../gt"))
_lambda.DockerImageFunction(self, id='gt_from_image', function_name="gt_from_image_Fn",
code=_lambda.DockerImageCode.from_ecr(
repository=asset_img.repository,
tag=asset_img.source_hash))
From the documentation for DockerImageCode.from_ecr(), it does not expect a scope argument, so your self argument is what is causing the error.
Another issue is that DockerImageAsset will not tag the image as latest, as that is against AWS best practices.
The easy way to achieve what you are doing is to use
DockerImageCode.from_image_asset().

aws Lex UI does not show lambda function from other account

My colleague created a lex chatbot. I have been working on a lambda function that queries an external database they want to use in their bot. I created an intent to access the function and then exported the intent. I set up the AWS IAM service role for amazon lex and created resource permissions using this (https://docs.aws.amazon.com/lambda/latest/dg/services-lex.html). Though to make it work I did --action lambda:* Still, while the import completes without error, the lambda function does not seem to have been imported into the intent. When the intent is added to a bot, the lambda function is blank and the drop-down menu does not show my lambda function as an option. Is there a way to make the function accessible in my colleague's account in setting up the intent?
There should be an easier way to do this, but this is the workflow that at least works, even if it is not elegant:
create lambda function and export as zip (I use the python-lambda library)
other user creates an empty lambda function (same name and python version)
other user imports zip in labmda
Create an intent in Lex and export (do not put the lambda function in this)
other user imports the intent
other user modifies the fulfillment section of the intent to include the lambda function they just created.
completely kludgy but does work. Still looking for another way to make it work.

Bad handler when deploying Lambda function via CloudFormation ZipFile

I am deploying a Lambda function (Python 3.6) named lambda_handler using CloudFormation by specifying the code in-line as described here.
The Lambda deploys properly, however when testing the function I see a "Bad Handler" exception.
What is the correct way to refer to the handler when passing the Handler parameter to Lambda?
Use the handler index.lambda_handler. Since there is no deployment package name when submitting in-line code via ZipFile, the prefix index is used instead.