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