Передача списка KeyValuePairs в шаблон AWS Cloudformation - PullRequest
1 голос
/ 29 октября 2019

Я создаю шаблон облачной информации для группы (~ 75) микросервисов, работающих в ECS. Существует шаблон верхнего уровня, который включает все микросервисы в виде вложенных стеков. Вместо того, чтобы создавать десятки различных файлов шаблонов для каждой из служб, я бы хотел, чтобы все микросервисы использовали один и тот же шаблон 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'

В 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"

Проблема заключается в том, что для многих микросервисов требуются дополнительные уникальные переменные среды. До сих пор я делал все возможные переменные в одном шаблоне со значениями по умолчанию ''. Но теперь 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'
          ...
          ...

Для любого данного микросервиса большинство из них являются просто пустыми переменными среды. Это становится очень громоздким и запутанным.

В идеале я хотел бы иметь возможность передать список 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"

и затем присоедините список !Ref Env к существующему списку общих переменных env.

Я искал максимум и минимум, но у меня естьне удалось найти жизнеспособное решение. Ближайшая ссылка от на этот вопрос почти два года назад без соответствующего ответа.

...