如何使用 CloudFormation 创建具有集成 RDS 的 AWS Elasticbeanstalk 应用程序?

Posted

技术标签:

【中文标题】如何使用 CloudFormation 创建具有集成 RDS 的 AWS Elasticbeanstalk 应用程序?【英文标题】:How to create AWS Elasticbeanstalk application with integrated RDS using CloudFormation? 【发布时间】:2020-01-28 18:48:18 【问题描述】:

我正在尝试为使用 Postgres 的 SpringBoot 应用程序设置 AWS 环境。 我决定使用 CloudFormation 来配置我的应用程序所需的所有 AWS 组件。

以下是成云模板app.json:


  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters": 
    "S3BucketName": 
      "Description": "S3 BucketName",
      "Type": "String"
    ,
    "S3FileName": 
      "Description": "Name of the jar/war file",
      "Type": "String"
    ,
    "DBName":
      "Default":"mytododb",
      "Description":"The database name",
      "Type":"String",
      "MinLength":"1",
      "MaxLength":"64",
      "AllowedPattern":"[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription":"must begin with a letter and contain only alphanumeric characters."
    ,
    "DBUser":
      "Description":"The database admin account username",
      "Type":"String",
      "MinLength":"1",
      "MaxLength":"16",
      "AllowedPattern":"[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription":"must begin with a letter and contain only alphanumeric characters."
    ,
    "DBPassword":
      "NoEcho":"true",
      "Description":"The database admin account password",
      "Type":"String",
      "MinLength":"8",
      "MaxLength":"41",
      "AllowedPattern":"[a-zA-Z0-9]*",
      "ConstraintDescription":"must contain only alphanumeric characters."
    ,
    "DBAllocatedStorage":
      "Default":"5",
      "Description":"The size of the database (Gb)",
      "Type":"Number",
      "MinValue":"5",
      "MaxValue":"1024",
      "ConstraintDescription":"must be between 5 and 1024Gb."
    ,
    "DBInstanceClass":
      "Default":"db.t2.micro",
      "Description":"The database instance type",
      "Type":"String",
      "ConstraintDescription":"must select a valid database instance type."
    ,
    "MultiAZDatabase":
      "Default":"false",
      "Description":"Create a multi-AZ RDS database instance",
      "Type":"String",
      "AllowedValues":[
        "true",
        "false"
      ],
      "ConstraintDescription":"must be either true or false."
    
  ,
  "Resources": 
    "SpringBootApplication": 
      "Type": "AWS::ElasticBeanstalk::Application",
      "Properties": 
        "Description":"Spring boot and elastic beanstalk"
      
    ,
    "SpringBootApplicationVersion": 
      "Type": "AWS::ElasticBeanstalk::ApplicationVersion",
      "Properties": 
        "ApplicationName":"Ref":"SpringBootApplication",
        "SourceBundle": 
          "S3Bucket": 
            "Ref": "S3BucketName"
          ,
          "S3Key": 
            "Ref": "S3FileName"
          
        
      
    ,
    "SpringBootBeanStalkConfigurationTemplate": 
      "Type": "AWS::ElasticBeanstalk::ConfigurationTemplate",
      "Properties": 
        "ApplicationName": "Ref":"SpringBootApplication",
        "Description":"A display of speed boot application",
        "OptionSettings": [
          
            "Namespace": "aws:rds:dbinstance",
            "OptionName": "DBAllocatedStorage",
            "Value": 
              "Ref": "DBAllocatedStorage"
            
          ,
          
            "Namespace": "aws:rds:dbinstance",
            "OptionName": "DBDeletionPolicy",
            "Value": "Delete"
          ,
          
            "Namespace": "aws:rds:dbinstance",
            "OptionName": "DBEngine",
            "Value": "postgres"
          ,
          
            "Namespace": "aws:rds:dbinstance",
            "OptionName": "DBEngineVersion",
            "Value": "10.4"
          ,
          
            "Namespace": "aws:rds:dbinstance",
            "OptionName": "DBInstanceClass",
            "Value":  "Ref": "DBInstanceClass" 
          ,
          
            "OptionName": "DBPassword",
            "Namespace": "aws:rds:dbinstance",
            "Value":  "Ref": "DBPassword" 
          ,
          
            "Namespace": "aws:rds:dbinstance",
            "OptionName": "DBUser",
            "Value":  "Ref": "DBUser" 
          ,
          
            "Namespace": "aws:rds:dbinstance",
            "OptionName": "MultiAZDatabase",
            "Value":  "Ref": "MultiAZDatabase" 
          
        ],
        "SolutionStackName": "64bit Amazon Linux 2018.03 v2.9.2 running Java 8"
      
    ,
    "SpringBootBeanstalkEnvironment": 
      "Type": "AWS::ElasticBeanstalk::Environment",
      "Properties": 
        "ApplicationName": "Ref":"SpringBootApplication",
        "EnvironmentName":"TodoAppEnvironment",
        "TemplateName": "Ref":"SpringBootBeanStalkConfigurationTemplate",
        "VersionLabel": "Ref": "SpringBootApplicationVersion"
      
    
  ,
  "Outputs": 
    "DevURL": 
      "Description": "The URL of the DEV Elastic Beanstalk environment",
      "Value": 
        "Fn::Join": [
          "",
          [
            
              "Fn::GetAtt": [
                "SpringBootBeanstalkEnvironment",
                "EndpointURL"
              ]
            
          ]
        ]
      ,
      "Export": 
        "Name": 
          "Fn::Sub": "$AWS::StackName-EndpointURL"
        
      
    
  


而参数文件parameters.json为:

[
  
    "ParameterKey": "DBUser",
    "ParameterValue": "myuser"
  ,
  
    "ParameterKey": "DBPassword",
    "ParameterValue": "secret"
  ,
  
    "ParameterKey": "S3BucketName",
    "ParameterValue": "todoapp"
  ,
  
    "ParameterKey": "S3FileName",
    "ParameterValue": "todo-api-spring-boot-0.0.1.jar"
  
]

我正在使用创建 CloudFormation 堆栈 aws cloudformation create-stack --template-body file://app.json --parameters file://parameters.json --stack-name=todo-stack

问题: 堆栈正在创建,但数据库 (RDS) 实例未创建,当我在管理控制台中看到应用程序的 ElasticBeanstalk 配置时,没有与应用程序关联的数据库配置。

我的期望/假设是通过在 OptionSettings 中配置各种 aws:rds:dbinstance 属性,一个 RDS 实例将被配置并与 ElasticBeanstalk 应用程序关联。

是我的理解有误还是我遗漏了任何其他设置?

PS: 这个想法是使用集成的 RDS,这样我就可以在我的应用程序中使用 RDS_HOST、RDS_PORT 等属性来连接数据库。

我能够配置单独的 RDS 资源并通过指定连接参数来连接到它。但我期望 OptionSettings 中的 aws:rds:dbinstance 属性会创建 RDS 并将其与 Elasticbeanstalk 应用程序相关联。如果不是这样,那么在 OptionSettings 中配置这些参数的目的是什么?

参考:

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-rdsdbinstance

https://github.com/metabase/metabase/blob/master/bin/aws-eb-docker/cloudformation-elasticbeanstalk.json.template

【问题讨论】:

我遇到了同样的问题。你最终找到解决方案了吗? 【参考方案1】:

我偶然发现了同样的问题,并在这里找到了某种答案:https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.managing.db.html

他们在那份文件中说:

您可以使用配置文件配置环境的数据库实例。使用 aws:rds:dbinstance 命名空间中的选项。以下示例将分配的数据库存储大小修改为 100 GB。

因此,OptionSettings 中的 aws:rds:dbinstance 属性仅用于修改现有数据库实例,而不是一开始就创建一个。

【讨论】:

【参考方案2】:

由于命名空间方法,RDS 创建未完成。基本上命名空间用于覆盖您创建的资源的默认属性。

所以解决方案是在“SpringBootBeanStalkConfigurationTemplate”之前包含 RDS 创建模板

  "Resources": 
    "RDS Creation": 
      
      "Type" : "AWS::RDS::DBInstance",
      "Properties" : 
          "AllocatedStorage" : String,
          "AllowMajorVersionUpgrade" : Boolean,
          "AssociatedRoles" : [ DBInstanceRole, ... ],
          "AutoMinorVersionUpgrade" : Boolean,
          "AvailabilityZone" : String,
          "BackupRetentionPeriod" : Integer,
          "CharacterSetName" : String,
          "CopyTagsToSnapshot" : Boolean,
          "DBClusterIdentifier" : String,
          "DBInstanceClass" : String,
          "DBInstanceIdentifier" : String,
          "DBName" : String,
          "DBParameterGroupName" : String,
          "DBSecurityGroups" : [ String, ... ],
          "DBSnapshotIdentifier" : String,
          "DBSubnetGroupName" : String,
          "DeleteAutomatedBackups" : Boolean,
          "DeletionProtection" : Boolean,
          "Domain" : String,
          "DomainIAMRoleName" : String,
          "EnableCloudwatchLogsExports" : [ String, ... ],
          "EnableIAMDatabaseAuthentication" : Boolean,
          "EnablePerformanceInsights" : Boolean,
          "Engine" : String,
          "EngineVersion" : String,
          "Iops" : Integer,
          "KmsKeyId" : String,
          "LicenseModel" : String,
          "MasterUsername" : String,
          "MasterUserPassword" : String,
          "MonitoringInterval" : Integer,
          "MonitoringRoleArn" : String,
          "MultiAZ" : Boolean,
          "OptionGroupName" : String,
          "PerformanceInsightsKMSKeyId" : String,
          "PerformanceInsightsRetentionPeriod" : Integer,
          "Port" : String,
          "PreferredBackupWindow" : String,
          "PreferredMaintenanceWindow" : String,
          "ProcessorFeatures" : [ ProcessorFeature, ... ],
          "PromotionTier" : Integer,
          "PubliclyAccessible" : Boolean,
          "SourceDBInstanceIdentifier" : String,
          "SourceRegion" : String,
          "StorageEncrypted" : Boolean,
          "StorageType" : String,
          "Tags" : [ Tag, ... ],
          "Timezone" : String,
          "UseDefaultProcessorFeatures" : Boolean,
          "VPCSecurityGroups" : [ String, ... ]
        
    
  

在此之后,您可以在其他资源中包含 RDS 参数,因为它将首先创建。

【讨论】:

感谢您的回复。我仍然不清楚在 OptionSettings 中配置“aws:rds:dbinstance”参数的目的是什么?

以上是关于如何使用 CloudFormation 创建具有集成 RDS 的 AWS Elasticbeanstalk 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 cloudformation 为 S3 存储桶设置半随机名称

DynamoDB 使用 Cloudformation 自动扩展

具有多种资源的 Cloudformation 模板

无法通过 cloudformation 创建具有自动缩放功能的 AWS EMR

AWS CloudFormation 创建堆栈与部署

如何使用单个 cloudformation 模板创建多个 Elasticbeanstalk 环境