CCCC
CCCC

Reputation: 6481

Aws cloudformation - how to use a string parameter to prevent repetitive use of same string

1.
In my code, string "HelloWorldApi" uses a lots as a ref.
Is it possbile to use my defined parameter "APIName" to replace the repeat string "HelloWorldApi",
so that I don't need to update those string 1 by 1 when I make another stack and rename the API?

{
    "AWSTemplateFormatVersion": "2010-09-09",
    
    "Parameters": {
      "APIName": {
        "Type": "String",
        "Default": "HelloWorldApi"
      }
    },
    "Resources": {
      "HelloWorldApi": {
        "Type": "AWS::ApiGateway::RestApi",
        "Properties": {
          "Name": "hello-api",
          "Description": "API used for practice",
          "FailOnWarnings": true
        }
      },
      "APIAuthorizer" :{
        "Type" : "AWS::ApiGateway::Authorizer",
        "Properties" : {
            "RestApiId" : {
              "Ref": "HelloWorldApi"
            }
          }
      },
      "BannerDBModel": {
          "Type" : "AWS::ApiGateway::Model",
          "Properties" : {
              "Name" : "postBannerModel",
              "RestApiId" : {
                "Ref": "HelloWorldApi"
              },
              "Schema" : {
                "$schema": "http://json-schema.org/draft-04/schema#",
                "title": "ProductsInputModel",
                "type": "object",
                "properties": {
                    "url": {"type": "string"}
                }                
              }
           }
      },
      "PostRequestValidator": {
        "Type" : "AWS::ApiGateway::RequestValidator",
        "Properties" : {
            "Name" : "PostRequestValidator",
            "RestApiId" : {
                "Ref": "HelloWorldApi"
            }
        }
      },
      "BannerResource": {
        "Type": "AWS::ApiGateway::Resource",
        "Properties": {
            "RestApiId": {
                "Ref": "HelloWorldApi"
            },
            "ParentId": {
                "Fn::GetAtt": [
                    "HelloWorldApi",
                    "RootResourceId"
                ]
            },
            "PathPart": "banner"
        }
      },
      "getBannerMethod": {
        "Type": "AWS::ApiGateway::Method",
        "DependsOn": ["HelloWorldApi"],
        "Properties": {
          "RestApiId": {
            "Ref": "HelloWorldApi"
          },
          "ResourceId": {
            "Ref": "BannerResource"
          },
          "HttpMethod": "GET",
          "AuthorizationType": "NONE"
        }
      },
      "Deployment": {
          "DependsOn": ["HelloWorldApi"],
          "Type": "AWS::ApiGateway::Deployment",
          "Properties": {
            "RestApiId": {
              "Ref": "HelloWorldApi"
            }
          }
      }
    }
  }

2.
Lets say I have already created a stack through below code, if the default value of APIName is accidentally set to HelloWorld which is different from original version, will the error shows instantly after I run updateStack?
What will happen then? Another API HelloWorld being created?

Updated Code according to the comment

{
    "AWSTemplateFormatVersion": "2010-09-09",
    
    "Parameters": {
      "RestAPI": {
        "Type": "String",
        "Default": "HelloWorldApi"
      }
    },
    "Resources": {
      "RestAPI": {
        "Type": "AWS::ApiGateway::RestApi",
        "Properties": {
          "Name": "hello-api",
          "Description": "API used for practice",
          "FailOnWarnings": true
        }
      },
      "APIAuthorizer" :{
        "Type" : "AWS::ApiGateway::Authorizer",
        "Properties" : {
            "RestApiId" : {
              "Ref": "RestAPI"
            }
          }
      },
      "BannerDBModel": {
          "Type" : "AWS::ApiGateway::Model",
          "Properties" : {
              "Name" : "postBannerModel",
              "RestApiId" : {
                "Ref": "RestAPI"
              },
              "Schema" : {
                "$schema": "http://json-schema.org/draft-04/schema#",
                "title": "ProductsInputModel",
                "type": "object",
                "properties": {
                    "url": {"type": "string"}
                }                
              }
           }
      }
    }
  }

Upvotes: 2

Views: 298

Answers (1)

Chris Williams
Chris Williams

Reputation: 35258

To reuse this template you should rename the resource named HelloWorldApi to something more generic.

If you currently renamed the resource and attempted to redeploy it would remove any resources that are associated with the HelloWorldApi API as well as the API itself whilst redeploying the API again.

The string you're using is referencing the AWS::ApiGateway::RestApi resource not the value in the APIName parameter. If you updated this parameter value at the moment it would not affect the stack as it appears as though it is not used.

In summary the referencing of the string HelloWorldApi in Resources is referring to the AWS::ApiGateway::RestApi resources logical name.

Ensure the resources do not share the same name as the parameters.

The template would look like the below

{
    "AWSTemplateFormatVersion": "2010-09-09",
    
    "Parameters": {
      "RestAPIName": {
        "Type": "String",
        "Default": "HelloWorldApi"
      }
    },
    "Resources": {
      "RestAPI": {
        "Type": "AWS::ApiGateway::RestApi",
        "Properties": {
          "Name": { "Ref": "RestAPIName" },
          "Description": "API used for practice",
          "FailOnWarnings": true
        }
      },
      "APIAuthorizer" :{
        "Type" : "AWS::ApiGateway::Authorizer",
        "Properties" : {
            "RestApiId" : {
              "Ref": "RestAPI"
            }
          }
      },
      "BannerDBModel": {
          "Type" : "AWS::ApiGateway::Model",
          "Properties" : {
              "Name" : "postBannerModel",
              "RestApiId" : {
                "Ref": "RestAPI"
              },
              "Schema" : {
                "$schema": "http://json-schema.org/draft-04/schema#",
                "title": "ProductsInputModel",
                "type": "object",
                "properties": {
                    "url": {"type": "string"}
                }                
              }
           }
      }
    }
  }

Upvotes: 1

Related Questions