Open cluggas opened 7 years ago
I got a workaround for this.. Apparently when using SAM (aws cloudformation deploy) it uses the transform (Transform: AWS::Serverless-2016-10-31) rule set in your template to generate all kind of "extra" resources. One of them is a aws::ApiGateway::stage
resource. The name of this resource is ServerlessApiStage
where ServerlessApi is the name of the AWS::Serverless::Api
resource.
This might be a documentation issue. We are using a standard mechanism for constructing resource names. You should be able to use "DependsOn" to chain the resource creation in correct order. I will update the docs to explain how the resource names are created.
I really don't understand why it's trying to redeploy my API gateway stages in the first place. If my function that an API gateway resource is using is pointing to ":Latest" then why do we need to redeploy?
I'm having similar issue.
I tried using DependsOn to specify that the BasePathMapping depends on my AWS::ApiGateway::DomainName
and AWS::Serverless::Api
resource, but it is still created before Stage is created. I'm guessing that's because Stage is a separate resource outside of AWS::Serverless::Api
.
Thanks to @jvanbrunschot-coolblue 's comment, I was able to find a workaround. It looks like ServerlessApiStage
is indeed a separate resource outside of AWS::Serverless::Api
, and is generated by the transform function. So my workaround is to figure out what the generated resource name would be for the stage and specify that in the DependsOn section of the AWS::ApiGateway::BasePathMapping
resource.
Indeed it seems to be a bug, which disregards the dependencies between these resources. I am using SAM CLI 0.4.0 and AWS CLI 1.11.131 and had the same problem.
In my case the final template generate by Cloudformation produced the stage name as a concatenation of my API logical name and word Stage
: <myApiLogicalName>Stage
.
Fixed the problem by adding a DependsOn
on AWS::ApiGateway::BasePathMapping
as seen below:
# ########################################################################
# Mobile API
apiMobile:
Type: 'AWS::Serverless::Api'
Properties:
Name: mobile-api
StageName: !FindInMap [ApiStage, !Ref Environment, stage]
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location: 's3://<redacted>/swagger.yaml'
EndpointConfiguration: REGIONAL
# ###################################################################
# Base Path Mapping
apiBasePathMapping:
Type: 'AWS::ApiGateway::BasePathMapping'
Properties:
BasePath: v1.0
Stage: !FindInMap [ApiStage, !Ref Environment, stage]
DomainName:
'Fn::Sub':
- 'mobile-api${Suffix}.<redacted>'
- Suffix: !FindInMap
- EnvironmentShort
- !Ref Environment
- suffix
RestApiId: !Ref apiMobile
DependsOn:
- apiMobileStage <------ Added explicit dependency
Hi, I had to add apiStage and not only Stage.
aws-cli/1.15.66 SAM CLI, version 0.5.0
Hi, So i was stuck in the same scenario and after a lot of help from the above comments and a little trial and error on my end. The format of the aws::ApiGateway::stage is => (name of the serverless api resource)(stage name)Stage
Adding a DomainName
property to the AWS::Serverless::API resources which configures this all for you is probably what we want here.
Having Domain and Certificate parameters makes sense to me. If Certificate is not passed AWS::Serverless::API could create AWS::CertificateManager::Certificate resource too.
Any update on this? Would great to make this easier. Ran into this problem again recently. If need to understand the inner of an abstraction (i.e SAM) in order to use it then surely it's not doing its job?
I added an RFC for this here https://github.com/awslabs/serverless-application-model/issues/783. I'm going to close out this issue as a workaround has been posted, and we have a path forward to a simpler solution.
Indeed it seems to be a bug, which disregards the dependencies between these resources. I am using SAM CLI 0.4.0 and AWS CLI 1.11.131 and had the same problem. In my case the final template generate by Cloudformation produced the stage name as a concatenation of my API logical name and word
Stage
:<myApiLogicalName>Stage
.Fixed the problem by adding a
DependsOn
onAWS::ApiGateway::BasePathMapping
as seen below:# ######################################################################## # Mobile API apiMobile: Type: 'AWS::Serverless::Api' Properties: Name: mobile-api StageName: !FindInMap [ApiStage, !Ref Environment, stage] DefinitionBody: 'Fn::Transform': Name: 'AWS::Include' Parameters: Location: 's3://<redacted>/swagger.yaml' EndpointConfiguration: REGIONAL # ################################################################### # Base Path Mapping apiBasePathMapping: Type: 'AWS::ApiGateway::BasePathMapping' Properties: BasePath: v1.0 Stage: !FindInMap [ApiStage, !Ref Environment, stage] DomainName: 'Fn::Sub': - 'mobile-api${Suffix}.<redacted>' - Suffix: !FindInMap - EnvironmentShort - !Ref Environment - suffix RestApiId: !Ref apiMobile DependsOn: - apiMobileStage <------ Added explicit dependency
THIS IS IT THANKS FOR TAKING ME OUT OF MY DESPERATION PIT
For me the solution was:
Resources:
Api:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Auth:
DefaultAuthorizer: NONE
BasePathMapping:
Type: AWS::ApiGateway::BasePathMapping
Properties:
DomainName: !Ref GatewayDomain
RestApiId: !Ref Api
Stage: !Ref Api.Stage
Notice the BasePathMapping.Stage
is set to !Ref Api.Stage
which creates tight coupling and removes potential user errors such as typos.
@ca0abinary Thanks for the comment! This will be a really good addition to the examples folder. Reopening this issue.
Indeed it seems to be a bug, which disregards the dependencies between these resources. I am using SAM CLI 0.4.0 and AWS CLI 1.11.131 and had the same problem. In my case the final template generate by Cloudformation produced the stage name as a concatenation of my API logical name and word
Stage
:<myApiLogicalName>Stage
. Fixed the problem by adding aDependsOn
onAWS::ApiGateway::BasePathMapping
as seen below:# ######################################################################## # Mobile API apiMobile: Type: 'AWS::Serverless::Api' Properties: Name: mobile-api StageName: !FindInMap [ApiStage, !Ref Environment, stage] DefinitionBody: 'Fn::Transform': Name: 'AWS::Include' Parameters: Location: 's3://<redacted>/swagger.yaml' EndpointConfiguration: REGIONAL # ################################################################### # Base Path Mapping apiBasePathMapping: Type: 'AWS::ApiGateway::BasePathMapping' Properties: BasePath: v1.0 Stage: !FindInMap [ApiStage, !Ref Environment, stage] DomainName: 'Fn::Sub': - 'mobile-api${Suffix}.<redacted>' - Suffix: !FindInMap - EnvironmentShort - !Ref Environment - suffix RestApiId: !Ref apiMobile DependsOn: - apiMobileStage <------ Added explicit dependency
THIS IS IT THANKS FOR TAKING ME OUT OF MY DESPERATION PIT
Thank you it worked for me SAM 0.22.0 I had the same issue: just refer the object with the same name plus stage. To verify you are referring the right resources compiled by sam, I suggest to run sam validate --debug
and verify the name :-) thank you again!
If anyone is using an Http protocol API and the AWS::ApiGatewayV2:ApiMapping
I solved this by referencing ServerlessHttpApiApiGatewayDefaultStage
for stage.
ApiMapping:
Type: AWS::ApiGatewayV2::ApiMapping
Properties:
ApiId: !Ref ServerlessHttpApi
DomainName: !Ref ApiDomainName
Stage: !Ref ServerlessHttpApiApiGatewayDefaultStage
@ca0abinary Use "!Ref Api.Stage" as reference works here!! Thanks!!!
it works perfect for me Use "!Ref Api.Stage"
I had this issue and not even AWS Support knew the answer 🤦
@ca0abinary 's solution worked perfectly.
This worked for me: https://github.com/aws/serverless-application-model/issues/192#issuecomment-351527399
Apparently this is still an issue.
Worked for me as well. Thank you.
Based on the link below this should have been fixed by adding a DependsOn
to <api‑LogicalId><stage‑name>Stage
(as documented in this link: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-generated-resources-api.html)
Template format error: Unresolved resource dependencies [RestAPIGatewaydevelopmentStage] in the Resources block of the template
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Parameters:
APIStageName:
Type: 'AWS::SSM::Parameter::Value<String>'
Description: The name of the stage to deploy the API to.
Default: /account/environment
Resources:
RestAPIGateway:
Type: AWS::ApiGateway::RestApi
...
APICustomDomainMapping:
Type: AWS::ApiGateway::BasePathMapping
DependsOn:
- RestAPIGatewaydevelopmentStage
Properties:
DomainName: !Ref APICustomDomain
RestApiId: !Ref RestAPIGateway
Stage: !Ref APIStageName
It is hard to believe that this issue has not been addressed after almost 5 years. It seems that adding an explicit dependson on the stage generated during translation should fix this.
We got this to work by adding a WaitConditionHandle
on the suggested stage name. Not clear why this does not work directly on the DependsOn
, but in case it matters we are using AWS CLI 2.0 from CodeBuild project using aws/codebuild/standard:5.0
image.
StageCreated:
Type: AWS::CloudFormation::WaitConditionHandle
Metadata:
Created: !Sub RestAPIGateway${APIStageName}Stage
APICustomDomainMapping:
Type: AWS::ApiGateway::BasePathMapping
DependsOn:
- StageCreated
The impact of this issue is that since it's a timing issue it some times work, so imagine it works in dev/test environments and it happens to fail in the production deployment, that would be a very bad experience.
The workaround does not seem to work for my client. I think the difference is that we're using a RestApi vs Api and maybe that's why the workaround doesn't work for us. Does anybody still have the issue?
Thank you @yaminir, I think we were finally able to fix this permanently by adding an explicit Stage
resource, which allowed us to create an explicit dependency:
RestAPIGateway:
Type: AWS::ApiGateway::RestApi
...
ApiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId: !Ref RestAPIGateway
APIGatewayStage:
Type: "AWS::ApiGateway::Stage"
Properties:
DeploymentId: !Ref ApiGatewayDeployment
RestApiId: !Ref RestAPIGateway
StageName: !Ref APIStageName
APICustomDomainMapping:
Type: AWS::ApiGateway::BasePathMapping
DependsOn:
- APIGatewayStage
Properties:
DomainName: !Ref APICustomDomain
RestApiId: !Ref RestAPIGateway
Stage: !Ref APIStageName
I ran into this when adding a custom domain name, resolved simply with DependsOn the API like:
MyCustomDomainName:
Type: AWS::ApiGateway::DomainName
Properties:
RegionalCertificateArn: arn:aws:acm:eu-west-1:2345678:certificate/0000000-11111-2222-3333-444444444
DomainName: some-api.prd.some-domain.com
SecurityPolicy: TLS_1_2
EndpointConfiguration:
Types:
- REGIONAL
DependsOn:
- yourRestAPIResource
Hello everyone,
Yes this error is mostly due the stage not being created yet. So youre trying to map the custom domain to something that doesnt exist. In my case i am using serverless framework and i could not find the mapping reference resource. In any case after lot of testing, using dependson with these solved for me.
DependsOn:
Indeed it seems to be a bug, which disregards the dependencies between these resources. I am using SAM CLI 0.4.0 and AWS CLI 1.11.131 and had the same problem. In my case the final template generate by Cloudformation produced the stage name as a concatenation of my API logical name and word
Stage
:<myApiLogicalName>Stage
.Fixed the problem by adding a
DependsOn
onAWS::ApiGateway::BasePathMapping
as seen below:# ######################################################################## # Mobile API apiMobile: Type: 'AWS::Serverless::Api' Properties: Name: mobile-api StageName: !FindInMap [ApiStage, !Ref Environment, stage] DefinitionBody: 'Fn::Transform': Name: 'AWS::Include' Parameters: Location: 's3://<redacted>/swagger.yaml' EndpointConfiguration: REGIONAL # ################################################################### # Base Path Mapping apiBasePathMapping: Type: 'AWS::ApiGateway::BasePathMapping' Properties: BasePath: v1.0 Stage: !FindInMap [ApiStage, !Ref Environment, stage] DomainName: 'Fn::Sub': - 'mobile-api${Suffix}.<redacted>' - Suffix: !FindInMap - EnvironmentShort - !Ref Environment - suffix RestApiId: !Ref apiMobile DependsOn: - apiMobileStage <------ Added explicit dependency
@rodmaz You saved my life, I was also hit by this
This was fixed for me by adding a Depends on
like follows
RestApi:
Type: AWS::Serverless::Api
ApiBasePathMapping
Type: AWS::ApiGateway::BasePathMapping
DependsOn:
-RestApiStage // the name of the AWS::Serverless::Api appeneded with Stage here the name is RestApi(line No 1) and the stage is appended
I have a SAM template deploying three resources: An ApiGateway, a Lambda Function and a ApiGateway BasePathMapping.
There is one parameter to the template called StageName, and this is used in two places:
When this stack is deployed, Cloud Formation deploys things in a strange order. It deploys the Api Gateway before the BasePathMapping, which you would expect, but deploying the ApiGateway stage is a separate step. It tries to deploy the BasePathMapping before the ApiGateway Stage, which results in the error:
This is totally underdtandable given it has not been created yet.
I have tried using the DependsOn property on the BasePathMapping resource to force it to get created after the ApiGateway. It does, but not after the ApiGateway stage.
Does anyone know a way around this? It feels like a bug with the AWS::Serverless::Api resource type. It clearly needs to create a Gateway and a Stage, but the should be done sequentially not not allow the BasePathMapping to be created in between.
Work arounds I don't like include: