CloudFormation在更新时不会部署到API网关阶段

时间:2017-01-02 08:25:05

标签: amazon-web-services aws-api-gateway amazon-cloudformation

当我使用带有API网关资源的模板运行CloudFormation deploy时,第一次运行它时,它会创建并部署到阶段。随后我运行它,它会更新资源但不会部署到各个阶段。

这种行为是否符合预期?如果是的话,我是如何在更新时将其部署到阶段的?

(Terraform提到类似的问题:https://github.com/hashicorp/terraform/issues/6613

9 个答案:

答案 0 :(得分:12)

似乎无论何时您的某个Cloudformation资源发生变化,都无法轻松创建新的部署。

解决这个问题的一种方法是使用Lambda支持的自定义资源(请参阅http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html)。

只有在您的某个资源更新后,Lambda才会创建新的部署。要确定您的某个资源是否已更新, 您可能需要围绕此API调用实现自定义逻辑:http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeStackEvents.html

为了触发自定义资源的更新,我建议您提供一个Cloudformation参数,用于强制更新自定义资源(例如当前时间或版本号)。

请注意,您必须在自定义资源中添加DependsOn子句,其中包含与您的API相关的所有资源。否则,可能会在更新所有API资源之前创建部署。

希望这有帮助。

答案 1 :(得分:5)

亚马逊的CloudFormation的话是:

  

AWS CloudFormation负责为您配置和配置这些资源   http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html

重新部署API不是一项配置任务......这是一项促销活动,是软件发布过程中的一个阶段。

  

AWS CodePipeline是一种持续交付服务,可用于建模,可视化和自动执行发布软件所需的步骤。   http://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html

CodePipeline还支持从管道中的Actions执行Lambda函数。因此,如前所述,创建一个Lambda函数来部署您的API,但是从Codepipeline而不是CloudFormation调用它。

详情请咨询此页: http://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html

答案 2 :(得分:3)

我使用的是上述方法,但部署API网关对我来说似乎很复杂。如果我们要更改资源名称,那么删除和重新创建资源会花费一些时间,这会增加应用程序的停机时间。

我遵循以下方法使用AWS CLI将API网关部署到阶段,并且不会影响Cloudformation堆栈的部署。

我正在做的是,在API网关的部署完成后,在AWS CLI命令下运行。它将使用最新更新来更新现有阶段。

aws apigateway create-deployment --rest-api-id tztstixfwj --stage-name stg --description 'Deployed from CLI'

答案 3 :(得分:2)

这里的答案是使用舞台的AutoDeploy属性:

  Stage:
    Type: AWS::ApiGatewayV2::Stage
    Properties:
      StageName: v1
      Description: 'API Version 1'
      ApiId: !Ref: myApi
      AutoDeploy: true

请注意,使用'AutoDeploy'时必须未指定'DeploymentId'属性。

在此处查看文档:{​​{3}}

答案 4 :(得分:1)

当您的模板指定部署时,CloudFormation仅在尚不存在时才创建该部署。当您尝试再次运行它时,它会发现该部署仍然存在,因此不会重新创建它,因此没有部署。您需要为该部署使用新的资源ID,以便它将创建一个新的部署。请阅读以下内容以获取更多信息:https://currentlyunnamed-theclassic.blogspot.com/2018/12/mastering-cloudformation-for-api.html

答案 5 :(得分:1)

在TheClassic链接的Blogspot帖子中(到目前为止,最好的答案!),请记住,如果没有使用可以插入有效时间戳记代替$ TIMESTAMP $的东西来生成模板,则必须使用时间戳或其他唯一ID手动更新。这是我的功能示例,它成功删除了现有部署并创建了一个新部署,但是当我要创建另一个变更集时,我将不得不手动更新这些唯一值:

    rDeployment05012019355:
        Type: AWS::ApiGateway::Deployment
        DependsOn: rApiGetMethod
        Properties:
            RestApiId:
                Fn::ImportValue: 
                    !Sub '${pApiCoreStackName}-RestApi'
            StageName: !Ref pStageName

    rCustomDomainPath:
        Type: AWS::ApiGateway::BasePathMapping
        DependsOn: [rDeployment05012019355]
        Properties:
            BasePath: !Ref pPathPart
            Stage: !Ref pStageName
            DomainName:
                Fn::ImportValue: 
                    !Sub '${pApiCoreStackName}-CustomDomainName'
            RestApiId:
                Fn::ImportValue: 
                    !Sub '${pApiCoreStackName}-RestApi'

答案 6 :(得分:1)

我可能来晚了,但是如果API资源发生更改,您可以重新部署这些选项,这可能对仍在寻找选项的人有所帮助-

  1. 尝试将AutoDeploy设置为true。如果使用的是V2版本的部署。请注意,您需要通过V2创建APIGW。 V1和V2彼此不兼容。 https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigatewayv2-stage.html#cfn-apigatewayv2-stage-autodeploy

  2. Lambda支持的自定义资源,Lambda依次调用createDeployment API-https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html

  3. CodePipeline,它具有一个调用Lambda函数的操作,就像自定义资源一样-https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html

  4. SAM(无服务器应用程序模型)遵循与CloudFormation相似的语法,该语法将资源创建简化为抽象,并使用那些来构建和部署普通的CloudFormation模板。 https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html

  5. 如果您正在使用任何抽象层(如Sceptre)来进行云形成,则可以对资源https://sceptre.cloudreach.com/2.3.0/docs/hooks.html

    进行任何更新后,通过钩子调用createDeployment

因为我一直使用Scepter进行Cloudformation部署,所以我选择了第三个选项。在权杖中实现钩子也很容易。

答案 7 :(得分:0)

使用SAM

AWS :: Serverless :: Api

这会在完成转换时为您完成部署

答案 8 :(得分:0)

这对我有用:

cfn.yml

APIGatewayStage: 类型:'AWS::ApiGateway::Stage' 特性: 舞台名称:!Ref 环境 DeploymentId: !Ref APIGatewayDeployment$TIMESTAMP$ RestApiId: !Ref APIGatewayRestAPI 变量: lambdaAlias: !Ref 环境 方法设置: - 资源路径:'/' 数据跟踪启用:真 HttpMethod: "" 日志级别:信息
指标启用:真 依赖于取决于: - liveLocationsAPIGatewayMethod - testJTAPIGatewayMethod

APIGatewayDeployment$TIMESTAMP$: 类型:'AWS::ApiGateway::Deployment' 特性: RestApiId: !Ref APIGatewayRestAPI 依赖于取决于: - liveLocationsAPIGatewayMethod - testJTAPIGatewayMethod

bitbucket-pipelines.yml

脚本: - python3 deploy_api.py

deploy_api.py

导入时间

file_name = 'infra/cfn.yml' ts = str(time.time()).split(".")[0] 打印(ts)

以 open(file_name, 'r') 作为文件: 文件数据 = file.read()

filedata = filedata.replace('$TIMESTAMP$', ts)

以 open(file_name, 'w') 作为文件: file.write(filedata)

================================================ ==========================

阅读本文了解更多信息:https://currentlyunnamed-theclassic.blogspot.com/2018/12/mastering-cloudformation-for-api.html