Describe the bug
I have a two AWS Projects, one is deployed with serverless (API Functions)
The other project is deployed using the amplify-cli.
amplify --version
3.0.0
Now I try to add two functions from the serverless function stack to the amplify grapql shema.
type Mutation {
createTask(relationId: String, task: String): String @function(name: "amplify-postTask")
}
type Mutation {
createComment(relationtId: String, comment: String): String @function(name: "amplify-postComment")
}
The first function gets successfully added to the API. When I add any other function from the same serverless project. The amplify push fails on create a AWS::IAM::Role
CREATE_FAILED ApiAmplifyCreateCommentLambdaDataSourceRole AWS::IAM::Role Tue Oct 22 2019 11:16:00 GMT+0200 (CEST) ManagerApiAmplif-vrfnhtkignam5ikmhbnrmokf4a-dev already exists in stack arn:aws:cloudformation:eu-west-1:*removed*:stack/manager-amplify-dev-20191021235616-apimanagerAmplifyApi-1L6WIZZ-FunctionDirectiveStack-T83KE07FL2WX/821bbb40-f44f-11e9-a8af-0afa58e29f3e
To Reproduce
Steps to reproduce the behavior:
Expected behaviour
The stack gets published without an AWS::IAM::Role already exists error.
I updated amplify to the latest version
npm i -g @aws-amplify/cli@latest
amplify --version
3.15.0
still the same issue
I get the same error when I try to change the function that I'm using. I also have some functions that are deployed via other methods (CDK to be more precise).
The problem happens when I change my schema.graphql file from this:
getSomeValue(id: String): String @function(name: "MyExternalFunction1")
to this:
getSomeValue(id: String): String @function(name: "MyExternalFunction2")
@Flos @boricic This looks like a bug. The IAM role creation looks at the first few chars of your function name and then create the corresponding IAM role name. Since the function names are similar - that's cause the IAM role name to clash and causing the deployment to fail. Just changing the name of the lambda function to be not similar is the workaround for now. But we'll look into fixing this.
Duplicate of #2468
@kaustavghosh06
The first few chars are the name of the other Project. I can't change it in a simple manner.
@Flos I tried to reproduce the issue with the following schema and the amplify push command succeeded:
type Todo @model {
id: ID!
name: String!
description: String
}
type Mutation {
createTask(relationId: String, task: String): String @function(name: "amplify-postTask")
createComment(relationtId: String, comment: String): String @function(name: "amplify-postComment")
}
The Rolename created for createTask mutation is the following
"RoleName": {
"Fn::If": [
"HasEnvironmentParameter",
{
"Fn::Join": [
"-",
[
"AmplifyPostTaskLambdaDataS",
{
"Ref": "GetAttGraphQLAPIApiId"
},
{
"Ref": "env"
}
]
]
},
{
"Fn::Join": [
"-",
[
"AmplifyPostTaskLambdaDataSourceRole",
{
"Ref": "GetAttGraphQLAPIApiId"
}
]
]
}
]
}
For createComment, it's the following
"RoleName": {
"Fn::If": [
"HasEnvironmentParameter",
{
"Fn::Join": [
"-",
[
"AmplifyPostCommentLambdaDa",
{
"Ref": "GetAttGraphQLAPIApiId"
},
{
"Ref": "env"
}
]
]
},
{
"Fn::Join": [
"-",
[
"AmplifyPostCommentLambdaDataSourceRol",
{
"Ref": "GetAttGraphQLAPIApiId"
}
]
]
}
]
}
As you can see the role names are different for both the function data source directives and there's no clashes in the namespace. There could be a potential name clash for longer function names - but not for your case.
Note: this is with the latest CLI version - 3.15.0
So the question is, are your function names "amplify-postTask" and "amplify-postComment"? or are they something different?
To be precise, only if the first 26 characters of your two functions are the same - only then you'll see the name clashes - We do this to prevent IAM role name character limit.
@kaustavghosh06
my project name is/was much longer, after shorting it, it works now also for me.
So it seems to be an issue only with "long" project/service names which then need to be the prefix of the functions.
Service name looked more like this: companyname-project-api-amplify
type Mutation {
createTask(relationId: String, task: String): String @function(name: "companyname-project-api-amplif-postTask")
createComment(relationtId: String, comment: String): String @function(name: "companyname-project-api-amplif-postComment")
}
This fails but as you say, the lengths is over 26 characters, and the first part ist always equal.
Maybe it makes more sense to use the last 26 characters? It will look a bit ugly but the chances are lower that it breaks.
Yeah. Will discuss with the team and make the change. Closing this as it's a duplicate of #2468