将 KeyValuePairs 列表传递给 AWS Cloudformation 模板

Bla*_*lam 6 amazon-web-services amazon-ecs aws-cloudformation microservices

我正在为 ECS 中运行的一堆 (~75) 微服务​​构建一个 cloudformation 模板。有一个顶级模板将所有微服务作为嵌套堆栈包含在内。我希望所有微服务都使用相同的microservice.yaml模板并使用参数来定义要运行的微服务,而不是为每个服务创建数十个不同的模板文件。

AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy a service into an ECS cluster
Parameters:
  ServiceName:
    Type: String
  ImageUrl:
    Type: String
  LogLevel:
    Type: String
    Default: debug
  NodeEnv:
    Type: String
    Default: integration

Resources:
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      RequiresCompatibilities: 
        - EC2
      ContainerDefinitions:
        - Name: !Ref 'ServiceName'
          Image: !Ref 'ImageUrl'
          Environment:
            - Name: LOG_LEVEL
              Value: !Ref 'LogLevel'
            - Name: NODE_ENV
              Value: !Ref 'NodeEnv'

  Service:
    Type: AWS::ECS::Service
    Properties:
      ServiceName: !Ref 'ServiceName'
      Cluster: !ImportValue production-infrastructure:ECSClusterName
      DesiredCount: 1
      TaskDefinition: !Ref 'TaskDefinition'
Run Code Online (Sandbox Code Playgroud)

master.yaml我将列出所有服务,如下所示:

FooBarMicroservice:
  Type: AWS::CloudFormation::Stack
  Properties:
    Parameters:
      ServiceName: fooBarMicroservice
      ImageUrl: !Join ['' , [ !Ref 'ECRHost', '/fooBarMicroservice']]
    TemplateURL: "https://mybucket.s3.amazonaws.com/cloudformation-templates/microservice.yaml"
Run Code Online (Sandbox Code Playgroud)

问题是许多微服务需要额外的独特环境变量。到目前为止,我所做的是将所有可能的变量添加到一个模板中,默认值为''. 但现在TaskDefinition开始看起来像这样:

TaskDefinition:
  Type: AWS::ECS::TaskDefinition
  Properties:
    RequiresCompatibilities: 
      - EC2
    ContainerDefinitions:
      - Name: !Ref 'ServiceName'
        Image: !Ref 'ImageUrl'
        Environment:
          - Name: LOG_LEVEL
            Value: !Ref 'LogLevel'
          - Name: NODE_ENV
            Value: !Ref 'NodeEnv'
          - Name: SMTP
            Value: !Ref 'SMTP'
          - Name: ACME_CLIENT_ID
            Value: !Ref 'AcmeClientId'
          - Name: ACME_SECRET
            Value: !Ref 'AcmeSecret'
          - Name: ACME_TIMEOUT
            Value: !Ref 'AcmeTimeout'
          - Name: FOO_WEBHOOK_ROUTE
            Value: !Ref 'FooWebhookRoute'
          - Name: EXPIRES_IN
            Value: !Ref 'expiresIn'
          ...
          ...
Run Code Online (Sandbox Code Playgroud)

对于任何给定的微服务,其中大部分只是空的环境变量。这变得非常笨拙和混乱。

理想情况下,我希望能够将 KeyValuesPairs 列表传递给microservice.yaml所有唯一的环境变量。像这样(不起作用):

FooBarMicroservice:
  Type: AWS::CloudFormation::Stack
  Properties:
    Parameters:
      ServiceName: fooBarMicroservice
      ImageUrl: !Join ['' , [ !Ref 'ECRHost', '/fooBarMicroservice']]
      Env:
        - Name: ACME_CLIENT_ID
          Value: 'AE4051DE41'
        - Name: ACME_SECRET
          Value: 'TdUGm6GR>nQp|q<'
    TemplateURL: "https://mybucket.s3.amazonaws.com/cloudformation-templates/microservice.yaml"
Run Code Online (Sandbox Code Playgroud)

然后将!Ref Env列表与现有的公共环境变量列表连接起来。

我搜索了高低,但一直无法找到可行的解决方案。最接近的参考来自大约两年前的这个问题,没有相关答案。