使用AWS CloudFormation添加环境变量会重置AWS Beanstalk应用

时间:2018-12-07 12:46:36

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

我有一个使用以下CloudFormation模板创建的AWS Beanstalk应用程序和环境:

MyApp:
    Type: 'AWS::ElasticBeanstalk::Application'
    Properties:
        ApplicationName: MyAppName

InitialApplication:
    Type: 'AWS::ElasticBeanstalk::ApplicationVersion'
    Properties:
        ApplicationName: !Ref MyApp
        Description: Version 1.0
        SourceBundle:
            S3Bucket: !Sub 'elasticbeanstalk-samples-${AWS::Region}'
            S3Key: ecs-sample.zip

AppEnvironment:
    Type: 'AWS::ElasticBeanstalk::Environment'
    Properties:
        ApplicationName: !Ref MyApp
        Description: staging
        TemplateName: !Ref AppConfigurationTemplate
        VersionLabel: !Ref InitialApplication

AppConfigurationTemplate:
    Type: 'AWS::ElasticBeanstalk::ConfigurationTemplate'
    DependsOn:
        - MySecurityGroup
    Properties:
        ApplicationName: !Ref MyApp
        Description: My Configuration Template
        SolutionStackName: '64bit Amazon Linux 2018.03 v2.11.2 running Multi-container Docker 18.03.1-ce (Generic)'
        OptionSettings:
            # Lots of options here

            # Application environment variables
            - Namespace: aws:elasticbeanstalk:application:environment
              OptionName: MY_APP_OPTION
              Value: SOME_VALUE

问题是,如果我向应用程序中添加环境变量(即在aws:elasticbeanstalk:application:environment名称空间中),则Beanstalk会将环境的应用程序版本重置为初始应用程序。因此,假设我在一年前创建了CloudFormation堆栈,并且已经部署了50个版本的应用程序...如果然后通过CloudFormation添加环境变量,则该环境的应用程序将重置为示例应用程序。当然,这将破坏一切,因为数据库已更改,等等。我想要的当然是添加/修改环境变量,而无需更改Beanstalk环境中已部署的应用程序版本。

为什么进行此更改时Beanstalk会重置我的应用程序,并且有什么方法可以阻止它?

谢谢!

3 个答案:

答案 0 :(得分:1)

不断更新最新的云形成是最佳实践,当然也建议这样做。如果您不这样做,那么您将陷入尴尬的境地,就像现在正在经历的那样,那是不幸的,但可以修复。您需要将CF模板中的捆绑源更新为最新版本,以便对其进行部署,因为它是一个未知的重大变化,可能需要重建基础结构

答案 1 :(得分:0)

这里要理解的一个重要概念是,如果可以初始化,然后通过EB控制台(如您所说的那样)或EB API上载新版本的应用程序,那么为什么实际上使用CloudFormation来部署应用程序。 CloudFormation是您的应用程序的一种“配方”,它的设计宗旨是keep the infrastructure definition under source control。这就是为什么在仅更新“配方”中的环境变量部分时会观察到回滚的原因-CloudFormation中所做的更改触发了应用程序中的更新,并且应用了模板中的定义-旧应用程序版本很难使用编码。这就是为什么理想情况下CloudFormation template should be parametrized的原因-每次您想要在应用程序中进行更新时,都应将最新的版本名称传递给模板。

您当然可以在其控制台中手动更新EB版本,但是在这种情况下,使用CloudFormation的整个想法变得毫无意义,并且会导致您所观察到的复杂性。

如注释中所指定,您可以将新的应用程序版本上载到S3,然后通过将版本作为参数传递的API通过CloudFormation进行更新。这样,更新可以自动化。一个示例API调用,用于在堆栈中进行一些更新(AWS docs中的解释):

aws cloudformation update-stack --stack-name mystack --template-url https://s3.amazonaws.com/sample/updated.template
--parameters ParameterKey=VPCID,ParameterValue=SampleVPCID ParameterKey=SubnetIDs,ParameterValue=SampleSubnetID1\\,UpdatedSampleSubnetID2

在您的情况下,要更新的参数将为AWS::ElasticBeanstalk::ApplicationVersion,尤其是SourceBundle

旧答案(在EB控制台中更新应用程序,而不接触CloudFormation)

我了解到您没有使用Cloud Formation模板部署应用程序(因为一年没有更新),因此您必须使用eb deploy或在Elastic Beanstalk控制台中以编程方式进行应用程序。那么为什么不在控制台中更新环境变量呢?

您可以通过以下方法进行操作:转到应用程序的控制台,单击左侧菜单中的“配置”,然后单击“软件”部分中的“修改”按钮。在底部,您可以添加每次新部署后应用程序中都会存在的环境变量。

答案 2 :(得分:-1)

您需要通过ChangeSet执行环境变量更改,以便仅执行环境变量更改,其余堆栈保持原样。