可以在Cloudformation中更新Elastic Beanstalk环境,而不会影响部署到它的版本吗?

时间:2018-02-14 16:23:07

标签: amazon-web-services elastic-beanstalk amazon-cloudformation amazon-elastic-beanstalk

我正在使用Cloudformation创建一个Elastic Beanstalk环境。我必须创建一个ApplicationVersion才能启动它并将其提供给环境定义。我创建了其他ApplicationVersions并以其他方式将它们部署到集群(CodePipeline)。

现在,每当我需要更新Cloudformation堆栈以更改其他基础架构时,即使它没有将其列为潜在的资源更改,它也会将ApplicationVersion回滚到初始堆栈,我不得不再次手动将环境更新到最新版本。

我知道发生了什么 - Cloudformation只是试图在模板描述它时保留堆栈。我只定义了最初的ApplicationVersion,因为它是Beanstalk环境的要求。还有其他办法吗?

3 个答案:

答案 0 :(得分:2)

CloudFormation希望掌控一切。根据您执行的堆栈更新,CloudFormation将根据模板中定义的内容重新创建版本。

不要将您的版本从Code Pipeline直接部署到Elastic Beanstalk,而是执行以下操作:

  1. 不要将初始版本硬编码到CloudFormation模板中。
  2. 将正在部署的版本挂钩到您的CloudFormation堆栈的输入参数。例如,将输入参数设置为版本内部版本号,并在模板中构建一个URL作为版本源。
  3. 部署时,指示代码管道使用更新的内部版本号更新堆栈。 CloudFormation应该通过构建新URL并部署版本来接管。
  4. 示例:

    假设您的堆栈中有参数ZipBucketZipObject,您可以在AWS::ElasticBeanstalk::ApplicationVersion资源上执行以下操作:

    "SourceBundle"    : {
        "S3Bucket" : {
            "Ref" : "ZipBucket"
        },
        "S3Key"    : {
            "Ref" : "ZipObject"
        }
    }
    

    另一种选择是使用BuildNumber参数,然后在Fn::Join属性中使用S3Key来构建内部版本号之外的URL。

答案 1 :(得分:0)

我一直在研究Elastic Beanstalk,CodePipeline和CloudFormation,并找到了一种方法来实现与您想要的(我认为)类似的东西。

我使用CloudFormation CLI(create-stack)和命令行中的单个模板来创建:

  • 使用“ Hello,World”应用程序的初始Elastic Beanstalk应用程序和环境,我之前已将其上传到S3存储桶
  • 用于GitHub集成的Web挂钩
  • CodePipeline连续交付管道

堆栈创建成功,最初我在Elastic Beanstalk上运行了我的“ Hello,World”应用程序。然后,我能够通过GitHub Web钩子和CodePipeline部署我的实际应用程序,从而覆盖了占位符应用程序。

我担心当我更改环境时(再次使用CloudFormation CLI,这次是使用create-change-setexecute-change-set),我将重新部署“ Hello,World”应用程序并覆盖我的 real ,但事实并非如此。我的基于GitHub的应用程序仍然是应用更改集之后部署的应用程序。请注意,对AWS::ElasticBeanstalk::ApplicationVersion的更改将导致在Elastic Beanstalk上部署新应用程序,并覆盖 real 版本。

这是一个不完善的解决方案,我不确定为什么AWS如此设计Elastic Beanstalk-CloudFormation-CodePipeline集成,并且感到很奇怪,必须先部署一个虚拟应用程序,然后再进行部署。我对Lambdas也有类似的头痛,所以我想这是设计使然,而不是疏忽大意。

答案 2 :(得分:0)

上面给出的答案似乎不正确 - 或者自编写以来 AWS 中的某些内容发生了变化。

根据我的经验,对 SourceBundle 中的 AWS::ElasticBeanstalk::ApplicationVersion 进行任何更改(无论是单独声明资源还是作为 ApplicationVersionsAWS::ElasticBeanstalk::Application 参数的一部分)都将导致执行变更集时出错。我收到的错误是“您无法更新 ApplicationVersions”。我是否更改描述似乎并不重要。

到目前为止我能想出的唯一解决方案是将我的 SourceBundle 指向一个不会改变的 url。例如,develop 用于开发环境,main 用于生产。在发布任何可能导致重新部署版本的更改集之前,我只需要确保在那里部署了我的最新代码。

如果我在这里遗漏了什么,我很想知道我的方法是否可以改进。