Description:
The 2016-10-31 docs state
SAM will generate an API Gateway Stage and API Gateway Deployment for every AWS::Serverless::Api resource. If you want to refer to these properties in an intrinsic function such as Ref or Fn::GetAtt, you can append .Stage and .Deployment suffix to the API's Logical ID. SAM will convert it to the correct Logical ID of the auto-generated Stage or Deployment resource respectively.
When I try to use !GetAtt Api.Stage I get the errors:
Template error: resource Api does not support attribute type Stage in Fn::GetAtt
or
Template error: resource Api does not support attribute type Deployment in Fn::GetAtt
Steps to reproduce the issue:
Template:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Bug demo
Resources:
Api:
Type: AWS::Serverless::Api
Properties:
StageName: "1"
DefinitionBody:
swagger: '2.0'
info:
description: Your first API with Amazon API Gateway. This is a sample API that integrates
via HTTP with our demo Pet Store endpoints
title: PetStore
schemes:
- https
paths:
"/":
get:
tags:
- pets
description: PetStore HTML web page containing API usage information
consumes:
- application/json
produces:
- text/html
responses:
'200':
description: Successful operation
headers:
Content-Type:
type: string
description: Media type of request
x-amazon-apigateway-integration:
responses:
default:
statusCode: '200'
responseParameters:
method.response.header.Content-Type: "'text/html'"
responseTemplates:
text/html: |-
<html>
<head>
<style>
body {
color: #333;
font-family: Sans-serif;
max-width: 800px;
margin: auto;
}
</style>
</head>
<body>
<h1>Welcome to your Pet Store API</h1>
<p>
You have succesfully deployed your first API. You are seeing this HTML page because the <code>GET</code> method to the root resource of your API returns this content as a Mock integration.
</p>
<p>
The Pet Store API contains the <code>/pets</code> and <code>/pets/{petId}</code> resources. By making a <a href="/$context.stage/pets/" target="_blank"><code>GET</code> request</a> to <code>/pets</code> you can retrieve a list of Pets in your API. If you are looking for a specific pet, for example the pet with ID 1, you can make a <a href="/$context.stage/pets/1" target="_blank"><code>GET</code> request</a> to <code>/pets/1</code>.
</p>
<p>
You can use a REST client such as <a href="https://www.getpostman.com/" target="_blank">Postman</a> to test the <code>POST</code> methods in your API to create a new pet. Use the sample body below to send the <code>POST</code> request:
</p>
<pre>
{
"type" : "cat",
"price" : 123.11
}
</pre>
</body>
</html>
passthroughBehavior: when_no_match
requestTemplates:
application/json: '{"statusCode": 200}'
type: mock
Outputs:
api:
Description: xxx
Value: !Ref Api
stage:
Description: xxx
Value: !GetAtt Api.Stage
deploy:
Description: xxx
Value: !GetAtt Api.Deployment
!Ref Api works fine. The other 2 outputs should work but do not.
Observed result:
Error(s) in Change sets:
Template error: resource Api does not support attribute type Stage in Fn::GetAtt
Template error: resource Api does not support attribute type Deployment in Fn::GetAtt
Expected result:
No errors and the Outputs show the Stage and Deployment physical ids.
You should use !Ref to access the .Stage and .Deployment physical ids.
For anyone in google-land looking to use these with !Sub, you can use the long form:
Outputs:
allthings:
Description: all the things
Value:
Fn::Sub:
- "api: ${api} - deploy: ${deploy} - stage: ${stage}"
- api: !Ref Api
deploy: !Ref Api.Deployment
stage: !Ref Api.Stage
Most helpful comment
For anyone in google-land looking to use these with !Sub, you can use the long form: