Реализовать в #CloudFormation #templates зависимость значений от environment не очень сложно. Однако когда требуется переменное количество параметров (т.е. для одного окружения один набор переменных, а для другого - отличный), то для этого Амазон сделал в своё время Fn::Transform.
Однако из-за того, что это (Transform) суть костыльный костыль, реализуемый как надстройка в виде лямбды, которая запускается перед скармливанием CloudFormation конечного вида шаблона, то реальный опыт работы с Transform оказался весьма болезненный.
Потому совет: если можно не использовать Transform - лучше не использовать.
Альтернативой может быть использование #Conditions.
Например, вот реальный кейс. Потребовалось для multi environment шаблона реализовать логику различного набора переменных для #ECS #task_definition - на тестовом окружении требовалось задать другие переменные, при этом обычные не должны быть определены совсем, т.к. чувствительное приложение, написанное в давние времена, спотыкалось о них и падало.
В результате дефолтная таска была скопирована и создана ещё одна такая же, только с нужными переменными. И добавлен волшебный condition, который из двух этих тасок в сервисе подключал нужную:
https://github.com/applerom/cloudformation-examples/blob/master/ecs/task-definition-with-different-set-of-variables.yaml
По умолчанию логика ни для какого (уже ранее имеющегося) окружения не поменяется (т.к. по умолчанию UseTestVariables = 'no'), а для тестового сработает
Итого - всё работает стандартно и без трансформатора.
Однако из-за того, что это (Transform) суть костыльный костыль, реализуемый как надстройка в виде лямбды, которая запускается перед скармливанием CloudFormation конечного вида шаблона, то реальный опыт работы с Transform оказался весьма болезненный.
Потому совет: если можно не использовать Transform - лучше не использовать.
Альтернативой может быть использование #Conditions.
Например, вот реальный кейс. Потребовалось для multi environment шаблона реализовать логику различного набора переменных для #ECS #task_definition - на тестовом окружении требовалось задать другие переменные, при этом обычные не должны быть определены совсем, т.к. чувствительное приложение, написанное в давние времена, спотыкалось о них и падало.
В результате дефолтная таска была скопирована и создана ещё одна такая же, только с нужными переменными. И добавлен волшебный condition, который из двух этих тасок в сервисе подключал нужную:
https://github.com/applerom/cloudformation-examples/blob/master/ecs/task-definition-with-different-set-of-variables.yaml
По умолчанию логика ни для какого (уже ранее имеющегося) окружения не поменяется (т.к. по умолчанию UseTestVariables = 'no'), а для тестового сработает
TaskDefinition: !If [ UseTest, !Ref ecsTaskTest, !Ref ecsTask ].Итого - всё работает стандартно и без трансформатора.
S3 Transfer Acceleration
Для случаев, когда нужно загружать в бакет быстро-много-часто и со всего мира, то на загрузку можно включить ускорение (кушает некоторые деньги):
#s3 #acceleration #CloudFormation #templates
Для случаев, когда нужно загружать в бакет быстро-много-часто и со всего мира, то на загрузку можно включить ускорение (кушает некоторые деньги):
bucketUploads:https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketUploads
AccelerateConfiguration:
AccelerationStatus: Enabled
#s3 #acceleration #CloudFormation #templates
Amazon
Configuring fast, secure file transfers using Amazon S3 Transfer Acceleration - Amazon Simple Storage Service
Get faster data transfers to and from Amazon S3 with Amazon S3 Transfer Acceleration.
CloudFormation development tool - Rain
Для тех, кто работает со стэками в командной строке - очередная попытка хоть как-то обустроить работу с #CloudFormation #templates:
https://github.com/aws-cloudformation/rain
Принцип работы можно понять по гифке в описании репозитория. Для простых вещей кому-то может оказаться полезно.
Для тех, кто работает со стэками в командной строке - очередная попытка хоть как-то обустроить работу с #CloudFormation #templates:
https://github.com/aws-cloudformation/rain
Принцип работы можно понять по гифке в описании репозитория. Для простых вещей кому-то может оказаться полезно.
GitHub
GitHub - aws-cloudformation/rain: A development workflow tool for working with AWS CloudFormation.
A development workflow tool for working with AWS CloudFormation. - aws-cloudformation/rain
Шаблон для VPC в N.Virginia с шестью AZ-подзонами
Многие примеры #CloudFormation #templates имеют в большинстве случаев две подзоны (Availability Zones). Это удобно тем, что все регионы имеют как раз минимум эти две подзоны (см. наверняка знакомую картинку из документации).
В большинстве случаев этого хватает - даёт минимальную надёжность и при этом не усложняет конфигурации огородом подсетей и прочих аттрибутов, сопутствующих каждой подзоне.
Но сетевую архитектуру плохо менять по ходу, а чаще просто невозможно. И потому какое-нибудь compliance с требованием трёх подзон, может оказаться неприятным сюрпризом, когда всё давно работает и не понятно, как переделывать. Или когда вы сами решите внедрить spot-инстансы, где принципиально иметь максимум подзон.
Особенно это актуально для N.Virginia, где целых 6 подзон. Использовать в таком регионе лишь 2-3 штуки из имеющихся шести - особо неприятно.
Для создания #VPC можно использовать кучи способов - от вручную в консоли до Terrafrorm и прочих инструментов. У каждого адепта #CloudFormation есть свои "проверенные" шаблоны, в частности, вот мой для региона
https://github.com/applerom/cloudformation-examples/blob/master/vpc/vpc4af.yml
В результате создаётся VPC с диапазоном адресов
Многие примеры #CloudFormation #templates имеют в большинстве случаев две подзоны (Availability Zones). Это удобно тем, что все регионы имеют как раз минимум эти две подзоны (см. наверняка знакомую картинку из документации).
В большинстве случаев этого хватает - даёт минимальную надёжность и при этом не усложняет конфигурации огородом подсетей и прочих аттрибутов, сопутствующих каждой подзоне.
Но сетевую архитектуру плохо менять по ходу, а чаще просто невозможно. И потому какое-нибудь compliance с требованием трёх подзон, может оказаться неприятным сюрпризом, когда всё давно работает и не понятно, как переделывать. Или когда вы сами решите внедрить spot-инстансы, где принципиально иметь максимум подзон.
Особенно это актуально для N.Virginia, где целых 6 подзон. Использовать в таком регионе лишь 2-3 штуки из имеющихся шести - особо неприятно.
Для создания #VPC можно использовать кучи способов - от вручную в консоли до Terrafrorm и прочих инструментов. У каждого адепта #CloudFormation есть свои "проверенные" шаблоны, в частности, вот мой для региона
us-east-1 с зонами от A до F (6 шт.):https://github.com/applerom/cloudformation-examples/blob/master/vpc/vpc4af.yml
В результате создаётся VPC с диапазоном адресов
/16 и с подсетями на /24, в том числе приватными (для которых по умолчанию создаётся NAT) - стандартный набор, короче. Просто с помощью данного шаблона всё это делается просто заданием CIDR prefix типа 10.25, а все остальные подсетки создадутся автоматом, что удобно и можно использовать единый стиль архитектуры со всеми своими проектами (подредактировав шаблон под свой вкус и прочие требования).Конвертилка существующих AWS ресурсов в CloudFormation шаблон
Стандартная ситуация условного стартапа в начальной стадии:
1. Накликали в AWS Console свой проект
2. Проект не загнулся и даже немножко поехал.
3. Запаривались эмулировать CI вручную.
4. Задумались о том, что нужно бы перести "вот это всё" в #CloudFormation #templates.
Возникает естественное и ненаказуемое желание — где бы найти утилитку, чтобы она автоматом сконвертила весь наш бедлам в один или парочку красивых шаблончиков.
Таких утилит не так много, они отличаются различной степенью бесполезности. Наименее бесполезная или, наоборот, наиболее полезная и самая красивая из них:
https://former2.com
Официальная же амазоновская называется CloudFormer:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-using-cloudformer.html
О бесполезности конвертошаблонизаторов
Сам я когда-то очень давно тоже начинал, а точней пытался начать с такой же штуки. Чуда не произойдёт не потому, что оно не работает, а по другой причине.
Если проект очень простой - посмотрев примерчики (в том числе мои), можно достаточно быстро накрапать нужное.
Если же проект сложный, то результатом работы "формеров" будет туча несвязанных элементов, в которых невозможно разобраться, т.к. ведь год генирируется автоматически.
Маловероятно, что он развернётся без ошибок (не сложно догадаться) и, само собой, не заработает как надо, даже или когда развернётся. Сгенерированную автоматом хрень отладить невозможно, а потому, как и я когда-то, в конце концов приведёте к выводу, что написать не столько проще, сколько это единственный вариант.
Ещё более единственным вариантом написание шаблона самостоятельно станет, когда будет осознан тот факт, что нужно также добавить в процесс создания переменные, которые могут что-то менять и отличаются для различных окружений, аккаунтов, регионов, назначений. Т.е. заложить в шаблон не только возможность автоматического разворачивания, но и организацию CI/CD-процесса с его помощью. А всё такое можно сделать лишь понимая зачем, для кого и самому.
Короче, всё печально, однако отговаривать не буду и обязательно попробуйте конвертилку в действии. Не стоит верить на слово — убедитесь лично.
#удачи
Стандартная ситуация условного стартапа в начальной стадии:
1. Накликали в AWS Console свой проект
2. Проект не загнулся и даже немножко поехал.
3. Запаривались эмулировать CI вручную.
4. Задумались о том, что нужно бы перести "вот это всё" в #CloudFormation #templates.
Возникает естественное и ненаказуемое желание — где бы найти утилитку, чтобы она автоматом сконвертила весь наш бедлам в один или парочку красивых шаблончиков.
Таких утилит не так много, они отличаются различной степенью бесполезности. Наименее бесполезная или, наоборот, наиболее полезная и самая красивая из них:
https://former2.com
Официальная же амазоновская называется CloudFormer:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-using-cloudformer.html
О бесполезности конвертошаблонизаторов
Сам я когда-то очень давно тоже начинал, а точней пытался начать с такой же штуки. Чуда не произойдёт не потому, что оно не работает, а по другой причине.
Если проект очень простой - посмотрев примерчики (в том числе мои), можно достаточно быстро накрапать нужное.
Если же проект сложный, то результатом работы "формеров" будет туча несвязанных элементов, в которых невозможно разобраться, т.к. ведь год генирируется автоматически.
Маловероятно, что он развернётся без ошибок (не сложно догадаться) и, само собой, не заработает как надо, даже или когда развернётся. Сгенерированную автоматом хрень отладить невозможно, а потому, как и я когда-то, в конце концов приведёте к выводу, что написать не столько проще, сколько это единственный вариант.
Ещё более единственным вариантом написание шаблона самостоятельно станет, когда будет осознан тот факт, что нужно также добавить в процесс создания переменные, которые могут что-то менять и отличаются для различных окружений, аккаунтов, регионов, назначений. Т.е. заложить в шаблон не только возможность автоматического разворачивания, но и организацию CI/CD-процесса с его помощью. А всё такое можно сделать лишь понимая зачем, для кого и самому.
Короче, всё печально, однако отговаривать не буду и обязательно попробуйте конвертилку в действии. Не стоит верить на слово — убедитесь лично.
#удачи
Последовательность блоков в #CloudFormation #templates можно менять (сначала ресурсы или даже вывод, остальное ниже):
Outputs: ecrRepository: Value: !Ref ecrRepositoryResources: ecrRepository: Type: AWS::ECR::Repository Properties: RepositoryName: !Ref RepositoryNameParameters: RepositoryName: Type: String Description: Name of ECR repository Default: some-repoDescription: ECR repositoryСоединение элементов строки в CloudFormation
Собрать в кучу строчку в CloudFormation шаблоне можно разными способами.
Стандартный с помощью !Join, например,
Однако длина не единственный показатель удобности и потому, когда вы после дебажите шаблон, все эти важные параметры сливаются на мониторе в строку (ведь это строка) и их не видно на фоне других. В то время как в случае
Так что я использую
Кстати, многие забывают, что у
В "солидной" версии это (не точный аналог - просто очень похожее из реального кода) будет длинным, но очевидным:
#CloudFormation #templates
Собрать в кучу строчку в CloudFormation шаблоне можно разными способами.
Стандартный с помощью !Join, например,
ContainerName: !Join ['-', ['service', !Ref MsName]]
Однако то же самое можно сделать с помощью !Sub:ContainerName: !Sub 'service-${MsName}'
То есть с !Sub олучается короче, иногда существенно короче. Потому такой подход весьма популярен.Однако длина не единственный показатель удобности и потому, когда вы после дебажите шаблон, все эти важные параметры сливаются на мониторе в строку (ведь это строка) и их не видно на фоне других. В то время как в случае
!Join чётко видны логические составляющие - все переменные, из которых будет собрана строка.Так что я использую
!Join - длиннее, но разборчивей.Кстати, многие забывают, что у
!Sub кроме "обычной" возможности просто вставлять параметры из шаблона, есть возможность подставлять их через свои переменные, организуя сложные выборки с !ImportValue и т.п. Например, вот здесь встречается такая конструкция:ResourceId: !SubЧтобы собрать строчку, мы внутри её делаем две свои "локальные" переменные
- 'service/${Cluster}/${Service}'
- Cluster: {'Fn::ImportValue': !Sub '${ParentClusterStack}-Cluster'}
Service: !GetAtt 'Service.Name
Cluster и Service (которые указывают после строки как массив) и уже в них делаем ещё какие-то действия.В "солидной" версии это (не точный аналог - просто очень похожее из реального кода) будет длинным, но очевидным:
ResourceId: !Join ['', ['service/', !ImportValue ecsClusterMs, '/', !GetAtt [ecsService, 'Name']]]
Всё видно и понятно. Как минимум мне.#CloudFormation #templates
Отличный источник примеров работы с #CloudFormation #templates (а также #Terraform и #aws_cli) плюс прямые ссылки на документацию, официальные блоги, всяческие безопасности и различные #best_practices:
https://asecure.cloud/
Однозначно в закладки.
#security #info
https://asecure.cloud/
Однозначно в закладки.
#security #info
Beanstalk + ALB + CloudFormation
По умолчанию в Elastic Beanstalk создаётся ALB, если делать это через консоль:
By default, Elastic Beanstalk creates an Application Load Balancer for your environment when you enable load balancing with the Elastic Beanstalk console or the EB CLI.
А через CloudFormation - с классическим ELB! (Здравствуй, логика.) Из-за этого в документации не найти примеров кода для создания Beanstalk в CloudFormation.
Cервис старый и все примеры в интернете обычно лишь для классического (старого) ELB. И документация из-за старости и сложности (под капотом) сервиса, весьма неочевидна.
Вот главная ссылка, что всегда требуется при создании шаблона для Beanstalk:
https://docs.amazonaws.cn/en_us/elasticbeanstalk/latest/dg/command-options-general.html
А вот пример кода, как заставить создать Beanstalk + ALB через CloudFormation:
#Beanstalk #CloudFormation #templates
По умолчанию в Elastic Beanstalk создаётся ALB, если делать это через консоль:
By default, Elastic Beanstalk creates an Application Load Balancer for your environment when you enable load balancing with the Elastic Beanstalk console or the EB CLI.
А через CloudFormation - с классическим ELB! (Здравствуй, логика.) Из-за этого в документации не найти примеров кода для создания Beanstalk в CloudFormation.
Cервис старый и все примеры в интернете обычно лишь для классического (старого) ELB. И документация из-за старости и сложности (под капотом) сервиса, весьма неочевидна.
Вот главная ссылка, что всегда требуется при создании шаблона для Beanstalk:
https://docs.amazonaws.cn/en_us/elasticbeanstalk/latest/dg/command-options-general.html
А вот пример кода, как заставить создать Beanstalk + ALB через CloudFormation:
- Namespace: aws:elasticbeanstalk:environmentПеременные нужно поменять на свои, главная оставить
OptionName: LoadBalancerType
Value: application
- Namespace: aws:elbv2:listener:443
OptionName: Protocol
Value: HTTPS
- Namespace: aws:elbv2:listener:443
OptionName: SSLCertificateArns
Value: !Ref AcmCertificateArn
- Namespace: aws:elbv2:listener:443
OptionName: DefaultProcess
Value: default
- Namespace: aws:elbv2:loadbalancer
OptionName: SecurityGroups
Value: !ImportValue sgVpc4Web
- Namespace: aws:elasticbeanstalk:environment:process:default
OptionName: Port
Value: !Ref InstancePort
- Namespace: aws:elasticbeanstalk:environment:process:default
OptionName: Protocol
Value: HTTP
- Namespace: aws:elasticbeanstalk:environment:process:default
OptionName: StickinessEnabled
Value: true
- Namespace: aws:elasticbeanstalk:environment:process:default
OptionName: HealthCheckPath
Value: !Ref HealthCheckPath
LoadBalancerType - application.#Beanstalk #CloudFormation #templates
ECS task + init container
Часто нужно, чтобы ECS
https://github.com/applerom/cloudformation-examples/blob/master/ecs/task-with-init-container.yaml
Код из рабочего конфига, но отредактирован (длинный, выброшено не относящееся к делу), чисто к тому, как такое можно сделать. В нём будут интересны следующие строчки.
...
...
...
...
Поднимаем
Контейнер для инициализации отрабатывает первым и умирает, потому ставим ему:
Он должен выполнить какую-то команду(-ы), запускаем следующим способом:
После него должен стартовать основной контейнер, чтобы реализовать такую последовательность (сначала - init, а уже потому главный), добавляем зависимость от первого:
И ставим главному контейнеру:
Так можно регулировать последовательность запуска и инициализировать что-то перед работой основного сервиса.
#CloudFormation #templates #examples
Часто нужно, чтобы ECS
task-а сначала была проиниацилизирована, а уже потом стартовал сервис. Пример, как такое можно сделать с помощью CloudFormation:https://github.com/applerom/cloudformation-examples/blob/master/ecs/task-with-init-container.yaml
Код из рабочего конфига, но отредактирован (длинный, выброшено не относящееся к делу), чисто к тому, как такое можно сделать. В нём будут интересны следующие строчки.
ecsTaskWithInit:
Type: AWS::ECS::TaskDefinition
Properties:
...
ContainerDefinitions:
- Name: !Ref StdNameInit
Image: !Ref DockerImage
Essential: false
...
Command:
- sh
- '-c'
- !Sub |
cd /home/my/app \
&& ./setup.py migrate --noinput \
&& ./setup.py rebuild_index --noinput
...
- Name: !Ref StdName
Image: !Ref DockerImage
Essential: true
Links:
- !Ref StdNameInit
Environment:
...
Поднимаем
task-у с двумя контейнерами - один будет для инициализации, а другой уже стартует сервис (это может быть один и тот же образ, лишь с разными переменными, как в данном случае).Контейнер для инициализации отрабатывает первым и умирает, потому ставим ему:
Essential: falseОн должен выполнить какую-то команду(-ы), запускаем следующим способом:
Command:
- sh
- '-c'
- !Sub |
cd /home/my/app \
&& ./setup.py migrate --noinput \
&& ./setup.py rebuild_index --noinput
После него должен стартовать основной контейнер, чтобы реализовать такую последовательность (сначала - init, а уже потому главный), добавляем зависимость от первого:
Links:
- !Ref StdNameInit
И ставим главному контейнеру:
Essential: trueТак можно регулировать последовательность запуска и инициализировать что-то перед работой основного сервиса.
#CloudFormation #templates #examples
GitHub
cloudformation-examples/ecs/task-with-init-container.yaml at master · applerom/cloudformation-examples
AWS CloudFormation code examples. Contribute to applerom/cloudformation-examples development by creating an account on GitHub.