I am trying to get used to the Java SDK for AWS but I am failing to get some basic stuff done. The code is supposed to do the following:
The code fails to properly deploy the desired resources because the Lambda cannot assume the role.
Please find below the code I am using. The various clients are properly initialized. Moreover:
bucketName
is a valid name of an existing S3 bucketobjectKey
is a valid name for an S3 key, no existing key matching this name in bucketName
bucketzipFile
is a File
pointing to a valid and existing zip file containing code for an AWS Lambda function handlerlambdaAssume
is a String
containing an assume role policy for lambda as described in the AWS documentation, it's content is shown after the codepolicyArn
is a valid ARN of an existing policys3Client.putObject(PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build(),
RequestBody.fromFile(zipFile));
Role execRole = iamClient.createRole(CreateRoleRequest.builder()
.roleName("my-new-lambda-exec-role")
.assumeRolePolicyDocument(lambdaAssume)
.build
).role();
lambdaClient.createFunction(CreateFunctionRequest.builder()
.functionName("my-new-lambda")
.packageType(PackageType.ZIP)
.code(FunctionCode.builder()
.s3Bucket(bucketName)
.s3Key(objectKey)
.build())
.role(execRole.arn())
.handler("org.acme.App::handleRequest")
.runtime(Runtime.JAVA11)
.architectures(Architecture.X86_64)
.build());
iamClient.attachRolePolicy(AttachRolePolicyRequest.builder()
.roleName(execRole.roleName())
.policyArn(policyArn)
.build());
where lambdaAssume
is as follows:
"""
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
"""
The code execution fails with the following error:
Exception in thread "main" software.amazon.awssdk.services.lambda.model.InvalidParameterValueException: The role defined for the function cannot be assumed by Lambda. (Service: Lambda, Status Code: 400, Request ID: ...)
Could anyone have a look at the code and tell me if I'm getting anything from? I also tried putting a waiter on the creation of the role but nothing changed. I've read on the aws console that when creating a lambda it might take up to 5 mins to get a newly created execution role to work and that it would be better not to modify it during that period. Would this apply also in the case of the SDK? (if so, wouldn't it be very bothersome? and how would I detect when the role is ready for modification?)
Please mind that the goal is to avoid creating resources by hand through the console, this means ideally everything is done through the sdk, with the possibility of using the cli but I would prefer to avoid that.
Thank you very much for anything you can help me with!
Looks like you may need to adjust your order. There is an example in the AWS Code example library in Java for IAM that does the creation of a role and adding a policy, and it has 30 sec waits after creating the resource. Maybe you would also want to catch a "role not found" exception (if there is one) and wait again and retry. But even with a wait, you would need one of the following orders:
OR
There is also a Lambda example in the library, but it uses a pre-existing role, so it doesn't exactly match your scenario.