Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions samtranslator/model/apigateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ def make_auto_deployable(
hash_input.append(str(openapi_version))
if domain:
hash_input.append(json.dumps(domain))
# Stage variables are applied with an UpdateStage call, which points the stage back at the
# deployment it already references. If they are not part of this hash, a variables-only
# change reuses the existing deployment: the new variables are never deployed, and any
# deployment made outside SAM since the last SAM deployment is reverted.
# Only added when set, so templates without stage variables keep their existing hash.
stage_variables = getattr(stage, "Variables", None)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[BUG] The hash uses the raw, unresolved stage.Variables, so the fix misses the common case where stage variables are parameter-driven. SamApi.to_cloudformation (samtranslator/model/sam_resources.py:1845-1847) runs resolve_parameter_refs over BinaryMediaTypes, Domain and Auth before constructing the generator, but never over self.Variables — it is passed through verbatim (line 1857) and lands on the stage unchanged (api_generator.py:463, and visible in tests/translator/output/intrinsic_functions.json:265 where the variables stay as Fn::Sub/Fn::Join).

So for a template like:

Parameters:
 EndpointUri:
   Type: String
Resources:
 MyApi:
   Type: AWS::Serverless::Api
   Properties:
     StageName: prod
     Variables:
       EndpointUri: !Ref EndpointUri

the hash input is always {"EndpointUri": {"Ref": "EndpointUri"}} regardless of the deployed parameter value. Deploying with a new value for EndpointUri still yields the same deployment logical id, which is exactly the failure described in #3703: the variable change is not deployed, and UpdateStage points the stage back at the SAM-known deployment. Domain does not have this problem precisely because it is resolved first.

Resolving the variables for hashing purposes would close the gap. Note that Domain is resolved by reassigning self.Domain, which also rewrites the emitted template; for Variables that would inline parameter values into the output AWS::ApiGateway::Stage, so prefer resolving into a separate value used only for the hash rather than mutating self.Variables.

Everything else checks out: stage.Variables is assigned before make_auto_deployable is called (api_generator.py:463 vs 470), that is the only call site, {} and None both fall through the if so no-variable templates keep their logical id, and the 24 fixture updates cover exactly the 8 input templates that set API stage variables across all three partitions, with the logical id, Description digest and Stage.DeploymentId ref updated consistently in each.

if stage_variables:
hash_input.append(json.dumps(stage_variables, sort_keys=True))
function_names = redeploy_restapi_parameters.get("function_names") if redeploy_restapi_parameters else None
# The deployment logical id is <api logicalId> + "Deployment"
# The keyword "Deployment" is removed and all the function names associated with api is obtained
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ExplicitApiDeployment9252467a1e": {
"ExplicitApiDeploymente24cb02185": {
"Properties": {
"Description": "RestApi deployment id: 9252467a1edc49ba35cb258640f5e3734cc9fab1",
"Description": "RestApi deployment id: e24cb0218583daf7c5e537a4e639dfb3a2971fdf",
"RestApiId": {
"Ref": "ExplicitApi"
},
Expand All @@ -70,7 +70,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ExplicitApiDeployment9252467a1e"
"Ref": "ExplicitApiDeploymente24cb02185"
},
"RestApiId": {
"Ref": "ExplicitApi"
Expand Down Expand Up @@ -230,9 +230,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ServerlessRestApiDeploymentdb4b9da82a": {
"ServerlessRestApiDeployment62318f9715": {
"Properties": {
"Description": "RestApi deployment id: db4b9da82adc6031fcd32bf3a4954485464fc009",
"Description": "RestApi deployment id: 62318f9715b2b5932b597575f6a4a0eafd0cf7e3",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
Expand All @@ -245,7 +245,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ServerlessRestApiDeploymentdb4b9da82a"
"Ref": "ServerlessRestApiDeployment62318f9715"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ExplicitApiDeployment7c4f7dda23": {
"ExplicitApiDeployment8e20079165": {
"Properties": {
"Description": "RestApi deployment id: 7c4f7dda23acd71e4a653861510d82ad7809e562",
"Description": "RestApi deployment id: 8e20079165a6421b14f28fc3f812a282e9ca3d90",
"RestApiId": {
"Ref": "ExplicitApi"
},
Expand All @@ -69,7 +69,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ExplicitApiDeployment7c4f7dda23"
"Ref": "ExplicitApiDeployment8e20079165"
},
"RestApiId": {
"Ref": "ExplicitApi"
Expand Down Expand Up @@ -267,9 +267,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ServerlessRestApiDeploymente091b9b9a0": {
"ServerlessRestApiDeployment26fa62bf10": {
"Properties": {
"Description": "RestApi deployment id: e091b9b9a0d7b8b9db6fee8c4ad295eb98edde08",
"Description": "RestApi deployment id: 26fa62bf10190a228c478ca0189e786b42e35acd",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
Expand All @@ -282,7 +282,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ServerlessRestApiDeploymente091b9b9a0"
"Ref": "ServerlessRestApiDeployment26fa62bf10"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ExplicitApiDeployment9252467a1e": {
"ExplicitApiDeploymente24cb02185": {
"Properties": {
"Description": "RestApi deployment id: 9252467a1edc49ba35cb258640f5e3734cc9fab1",
"Description": "RestApi deployment id: e24cb0218583daf7c5e537a4e639dfb3a2971fdf",
"RestApiId": {
"Ref": "ExplicitApi"
},
Expand All @@ -78,7 +78,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ExplicitApiDeployment9252467a1e"
"Ref": "ExplicitApiDeploymente24cb02185"
},
"RestApiId": {
"Ref": "ExplicitApi"
Expand Down Expand Up @@ -246,9 +246,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ServerlessRestApiDeploymente1212668e0": {
"ServerlessRestApiDeployment409ed00828": {
"Properties": {
"Description": "RestApi deployment id: e1212668e096994ab32167666f5a877bd6ac5fad",
"Description": "RestApi deployment id: 409ed008280bb6489cdd1707ff7f2b66d5ad40bb",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
Expand All @@ -261,7 +261,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ServerlessRestApiDeploymente1212668e0"
"Ref": "ServerlessRestApiDeployment409ed00828"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ExplicitApiDeployment7c4f7dda23": {
"ExplicitApiDeployment8e20079165": {
"Properties": {
"Description": "RestApi deployment id: 7c4f7dda23acd71e4a653861510d82ad7809e562",
"Description": "RestApi deployment id: 8e20079165a6421b14f28fc3f812a282e9ca3d90",
"RestApiId": {
"Ref": "ExplicitApi"
},
Expand All @@ -77,7 +77,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ExplicitApiDeployment7c4f7dda23"
"Ref": "ExplicitApiDeployment8e20079165"
},
"RestApiId": {
"Ref": "ExplicitApi"
Expand Down Expand Up @@ -283,9 +283,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ServerlessRestApiDeployment614ec93e15": {
"ServerlessRestApiDeploymente8a33c953e": {
"Properties": {
"Description": "RestApi deployment id: 614ec93e159f50797f73789c416660484070ee2e",
"Description": "RestApi deployment id: e8a33c953ef3abf412bc61a49eecc59a9eb71bc8",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
Expand All @@ -298,7 +298,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ServerlessRestApiDeployment614ec93e15"
"Ref": "ServerlessRestApiDeploymente8a33c953e"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
Expand Down
6 changes: 3 additions & 3 deletions tests/translator/output/aws-cn/explicit_api.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"GetHtmlApiDeploymentf117c932f7": {
"GetHtmlApiDeployment03f2a64f84": {
"Properties": {
"Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289",
"Description": "RestApi deployment id: 03f2a64f84966e7db9bc90b90fda3247d9a394d2",
"RestApiId": {
"Ref": "GetHtmlApi"
},
Expand All @@ -82,7 +82,7 @@
"GetHtmlApiStage": {
"Properties": {
"DeploymentId": {
"Ref": "GetHtmlApiDeploymentf117c932f7"
"Ref": "GetHtmlApiDeployment03f2a64f84"
},
"RestApiId": {
"Ref": "GetHtmlApi"
Expand Down
6 changes: 3 additions & 3 deletions tests/translator/output/aws-cn/explicit_api_openapi_3.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"GetHtmlApiDeploymentf117c932f7": {
"GetHtmlApiDeployment03f2a64f84": {
"Properties": {
"Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289",
"Description": "RestApi deployment id: 03f2a64f84966e7db9bc90b90fda3247d9a394d2",
"RestApiId": {
"Ref": "GetHtmlApi"
},
Expand All @@ -81,7 +81,7 @@
"GetHtmlApiStage": {
"Properties": {
"DeploymentId": {
"Ref": "GetHtmlApiDeploymentf117c932f7"
"Ref": "GetHtmlApiDeployment03f2a64f84"
},
"RestApiId": {
"Ref": "GetHtmlApi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"GetHtmlApiDeploymentf117c932f7": {
"GetHtmlApiDeployment2acb558823": {
"Properties": {
"Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289",
"Description": "RestApi deployment id: 2acb558823d4068b07590e8cd40633b8597a3157",
"RestApiId": {
"Ref": "GetHtmlApi"
},
Expand All @@ -37,7 +37,7 @@
"GetHtmlApiStage": {
"Properties": {
"DeploymentId": {
"Ref": "GetHtmlApiDeploymentf117c932f7"
"Ref": "GetHtmlApiDeployment2acb558823"
},
"RestApiId": {
"Ref": "GetHtmlApi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ExplicitApiDeployment9a254aa466": {
"ExplicitApiDeployment31e389dd75": {
"Properties": {
"Description": "RestApi deployment id: 9a254aa466c6f818951dfb6e45fde65489beb153",
"Description": "RestApi deployment id: 31e389dd75bba46beb7a57c4256c48c5a9b127f4",
"RestApiId": {
"Ref": "ExplicitApi"
},
Expand All @@ -85,7 +85,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ExplicitApiDeployment9a254aa466"
"Ref": "ExplicitApiDeployment31e389dd75"
},
"RestApiId": {
"Ref": "ExplicitApi"
Expand Down Expand Up @@ -253,9 +253,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ServerlessRestApiDeploymente1212668e0": {
"ServerlessRestApiDeployment409ed00828": {
"Properties": {
"Description": "RestApi deployment id: e1212668e096994ab32167666f5a877bd6ac5fad",
"Description": "RestApi deployment id: 409ed008280bb6489cdd1707ff7f2b66d5ad40bb",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
Expand All @@ -268,7 +268,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ServerlessRestApiDeploymente1212668e0"
"Ref": "ServerlessRestApiDeployment409ed00828"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
Expand Down
12 changes: 6 additions & 6 deletions tests/translator/output/aws-cn/globals_for_api.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ExplicitApiDeployment43e01e673d": {
"ExplicitApiDeployment0b29d48047": {
"Properties": {
"Description": "RestApi deployment id: 43e01e673d7acbd09e4c38ff78dd6ddaf2ed1d55",
"Description": "RestApi deployment id: 0b29d480473c478bb1a2337fdc7ff0b80bbe48cd",
"RestApiId": {
"Ref": "ExplicitApi"
},
Expand All @@ -84,7 +84,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ExplicitApiDeployment43e01e673d"
"Ref": "ExplicitApiDeployment0b29d48047"
},
"RestApiId": {
"Ref": "ExplicitApi"
Expand Down Expand Up @@ -260,9 +260,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ServerlessRestApiDeploymentf6c326a165": {
"ServerlessRestApiDeployment3556755163": {
"Properties": {
"Description": "RestApi deployment id: f6c326a1656cc9fbb0106cc645598d88575554eb",
"Description": "RestApi deployment id: 3556755163aac22f1710a4c6babf8de8932e55b6",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
Expand All @@ -275,7 +275,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ServerlessRestApiDeploymentf6c326a165"
"Ref": "ServerlessRestApiDeployment3556755163"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
Expand Down
6 changes: 3 additions & 3 deletions tests/translator/output/aws-cn/intrinsic_functions.json
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"MyExplicitApiDeployment7145dd00ce": {
"MyExplicitApiDeployment011ab6fdbf": {
"Properties": {
"Description": "RestApi deployment id: 7145dd00cea59b4a62b4d7855add490c587f3f62",
"Description": "RestApi deployment id: 011ab6fdbfec2a0b749690c4c389b4f44e51a053",
"RestApiId": {
"Ref": "MyExplicitApi"
},
Expand All @@ -272,7 +272,7 @@
"MyExplicitApidevStage": {
"Properties": {
"DeploymentId": {
"Ref": "MyExplicitApiDeployment7145dd00ce"
"Ref": "MyExplicitApiDeployment011ab6fdbf"
},
"RestApiId": {
"Ref": "MyExplicitApi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ExplicitApiDeployment9252467a1e": {
"ExplicitApiDeploymente24cb02185": {
"Properties": {
"Description": "RestApi deployment id: 9252467a1edc49ba35cb258640f5e3734cc9fab1",
"Description": "RestApi deployment id: e24cb0218583daf7c5e537a4e639dfb3a2971fdf",
"RestApiId": {
"Ref": "ExplicitApi"
},
Expand All @@ -78,7 +78,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ExplicitApiDeployment9252467a1e"
"Ref": "ExplicitApiDeploymente24cb02185"
},
"RestApiId": {
"Ref": "ExplicitApi"
Expand Down Expand Up @@ -246,9 +246,9 @@
},
"Type": "AWS::ApiGateway::RestApi"
},
"ServerlessRestApiDeploymentc969c99f9d": {
"ServerlessRestApiDeployment6ba28851eb": {
"Properties": {
"Description": "RestApi deployment id: c969c99f9d6b6921dff605a206e8989bdb7d1bc7",
"Description": "RestApi deployment id: 6ba28851eb50150f1e4349e33bc5185400c063d9",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
Expand All @@ -261,7 +261,7 @@
"CacheClusterEnabled": true,
"CacheClusterSize": "1.6",
"DeploymentId": {
"Ref": "ServerlessRestApiDeploymentc969c99f9d"
"Ref": "ServerlessRestApiDeployment6ba28851eb"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
Expand Down
Loading