AWS Notes
Открыть в Telegram
AWS Notes — Amazon Web Services Educational and Information Channel Chat: https://t.me/aws_notes_chat Contacts: @apple_rom, https://www.linkedin.com/in/roman-siewko/ No ads.
Больше5 796
Подписчики
-324 часа
-67 дней
-730 день
Архив постов
5 801
Nested Stacks
Не один год используя Nested Stacks , могу посоветовать - никогда не используйте #nested_stacks. Хуже #nested_stacks может быть лишь #nested_stacks на JSON.
Когда-то давно появление #nested_stacks казалось серьёзным шагом вперёд в попытке получения хоть какой-то модульности в #CloudFormation #templates, где до этого приходилось постоянно дублировать повторяющиеся части кода в шаблонах, отличающихся лишь малой частью ресурсов. Однако реальная эксплуатация показала, что с ростом сложности проекта, глубины и количества Nested Stacks, разрабатываться, сопровождать и обновлять его становится от сложно до невозможно.
Это потому, что для передачи параметров используется главный стэк, а запуская его на обновление, если у тебя отвалится что-то на энном обновляемом по уровню стэке, то сработает откат, который должен будет вернуть к предыдущему состоянию (успешно) обновившиеся до этого стэки, что банально не всегда возможно. Т.е. с постоянным усложнением проекта вам приходится быть как на картинке внизу.
Другая важная проблема, что из-за передачи переменных в низлежащие стэки через главный стэк, вы очень скоро можете попасть в ограничение на количество переменных, которое равно 60. Это для одного стэка кажется достаточным, но когда у вас даже пять-шесть вложенных стэков, то десяток переменных на каждого может сразу же исчерпают этот лимит.
Потому рекомендация одна - избегайте #nested_stacks. Они применимы лишь в примитивных случаях. Появление Import/Export функционала в CloudFormation практически убило какие-то реальные кейсы использования #nested_stacks. Если же вам досталась это чудо по наследству и вы попали на ограничение по количеству параметров (а вам нужно добавить новые) - используйте SSM параметры, передавая переменные через них.
5 801
Просто оставлю это здесь - интересная утилита, реализующая traffic mirroring:
https://github.com/buger/goreplay
Кому интересно, чуть расшифрую (не про Амазон).
Тестирование почти всегда проводится какими-то искусственными паттернами, которые должны при это дать некую гарантию, что на проде при реальной нагрузке оно не поломается. А метод traffic mirroring (или shadow traffic) дублирует реальный трафик, пришедший на прод в нужное вам (тестовое) окружение.
Это очень круто - иметь возможность тестировать "живым" трафиком. Модная тема, особенно легко реализуемая с помощью #kubernetes, так что советую как минимум знать про это - сие есть следующая инкарнация подходов Blue/Green или Canary Deployment.
5 801
Если у вас годами себе мирно жили тучи файлов на #s3 и вдруг выясняется, что по #compliance причинам теперь их всех нужно зашифровать либо по требованиями аудита требуется всем проставить (переставить) тэги или ещё какая-то глобально-массовая напасть — для всех таких работ теперь есть нативный инструмент #s3_batch_operations:
https://aws.amazon.com/blogs/aws/new-amazon-s3-batch-operations/
5 801
Сам я не пользуюсь врапперами/генераторами для #CloudFormation типа Stacker или Troposphere, однако для любителей такого подхода есть ещё одна полезная утилитка Sceptre:
https://github.com/cloudreach/sceptre
5 801
Ещё один ресурс для возможности сравнения EC2 инстансов - с некоторыми претензиями на мобильную версию:
https://cloudbanshee.com/ec2
Кстати, кто активно пользуется https://ec2instances.info и кому чего-то там не хватает — может вполне такое сделать сам:
https://github.com/powdahound/ec2instances.info
#info #comparison
5 801
Поддержка Secrets в Environment для #Fargate появилась в конце 2018-го года (версия Fargate 1.3), но на текущий момент в документации есть только следующее. Получается, это можно реализовать и в #CloudFormation #templates, однако документация, как обычно, отстаёт и хромает, хотя это уже работает.
Предположим, что нужно поднять какой-то Fargate контейнер, создать для него #SSM_Parameters, которые прокидываются в докер Environment, чтобы после можно было поменять нужный параметр без пересоздания всего стэка (для применения, естественно, потребуется пересоздание таски).
Главная часть кода для имплементации такого будет следующая:
...
ssmparamDbEndpoint:
Type: AWS::SSM::Parameter
Properties:
Name: !Ref ParamNameDbEndpoint
Type: String
Value: !Ref DbEndpoint
Description: SSM Parameter for DB endpoint
...
fargateTask:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions:
- Name: !Ref ServiceName
Image: !Ref DockerImage
Essential: true
Secrets:
- Name: WORDPRESS_DB_HOST
ValueFrom: !Join ['',['arn:aws:ssm:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':parameter/', !Ref ParamNameDbEndpoint]]
- Name: WORDPRESS_DB_USER
ValueFrom: !Join ['',['arn:aws:ssm:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':parameter/', !Ref ParamNameDbUser]]
- Name: WORDPRESS_DB_PASSWORD
ValueFrom: !Join ['',['arn:aws:ssm:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':parameter/', !Ref ParamNameDbPassword]]
Environment:
- Name: WORDPRESS_DB_NAME
Value: wp-db
...
Т.е. добавляется блок Secrets, куда значения из #ParameterStore попадают благодаря такой конструкции:
arn:aws:ssm:YOUR_AWS_REGION:YOUR_AWS_ACCOUNT:parameter/PARAMETER_NAME
Полный (рабочий) пример тут.
На текущий момент параметры из блока Secrets не отображаются в AWS Console (см. картинку внизу - она из примера), однако точно работают (можно попробовать пример). Хотя с некоторыми регионами могут быть вопросы - точно работает (проверено) для Virginia и Ireland.5 801
При создании #security_group в #CloudFormation #templates не забывайте (не ленитесь) прописать Description в ингрессах (в каждом) — сами себе скажете спасибо в будущем, не говоря уже про других.
sgInstance:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !ImportValue vpc4
GroupDescription: Std Security Group
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 0
ToPort: 65535
SourceSecurityGroupId: !Ref sgAlb
Description: All TCP trafic - only for ALB
- IpProtocol: tcp
FromPort: 9100
ToPort: 9100
CidrIp: 10.0.0.0/8
Description: node-exporter
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
CidrIp: 10.0.0.0/8
Description: cadvisor5 801
В пандан к предыдущему посту - заслуживающая внимания утилита для вычисления минимально нужных #IAM привилегий посредством сравнения имеющихся политик у юзера/роли и тех, что реально запрашиваются через AWS API (определяется с помощью #CloudTrail логов).
Может особенно может быть полезной для адептов #single_account, где такое весьма актуально в каждодневной борьбе с желающими урвать себе прав и побольше.
С помощью утилиты CloudTracker можно чётко контролировать используемое: кто не оценил вашу доброту - отобрать лишнее, а всем остальным выдавать доступ строго по талонам.
https://github.com/duo-labs/cloudtracker
5 801
Не все йогурты одинаково полезны, а потому с Managed #IAM политиками нужно быть на чеку (амазоновцы не парятся и ставят "с запасом" - многие имеют излишние права).
Чтобы знать врага в лицо, добрые люди собрали коллекцию IAM Managed политик и ведут историю их изменений:
https://github.com/SummitRoute/aws_managed_policies/tree/master/policies
5 801
Дальнейшее усложнение AWS #Organizations происходит по мере увеличения количества проектов, команд, требований и т.д.
===
Расширенная схема
===
• Общие ресурсы (ECR, снэпшоты, AMI и др.) вместе с #Shared_VPC выделяются в Shared аккаунт.
• Централизованный мониторинг и логи (ELK/Prometheus/Grafana/Sentry и т.д.) занимают свой аккаунт Monitoring (логи прода могут отправляться туда же или в отдельные - тут чисто условно).
• Бэкапы переезжают в DR (Disaster Recovery) аккаунты своих проектов.
• Наборы окружений dev-test-stg-prod-dr объединяются в #OU (Organization Units) для возможности применения к ним групповых SCP политик (объединение может быть и как Dev OU, DR OU etc - тоже чисто условно).
• Если ваша контора хочет целиком переехать в AWS, то выделяется отдельный аккаунт Organization для "организационных" вещей (название не самое удачное, речь об организации-фирме-компании, где, видимо, вы работаете :) ) — AD (Active Directory) для юзеров (самих работников), используемые для #SSO как единой точки входа, а также финансы, биллинги и прочие бухгалтерии, которые совсем не про код - всё будет там.
Процесс детализации #multi_account_strategy можно продолжать дальше - например, добавить OU для #HIPAA и прочих #compliance, где посредством #SCP будут отрабатывать их требования. Многие используеют Sandbox и/или личные аккаунты для разработчиков. И так далее и тому подобное — основные типы уже были перечислены и это уже лишь детали.
5 801
Минимальная схема не является рекомендованной, т.к. поднятие ресурсов в мастер-аккаунте не есть #best_practices. Согласно оным мастер-аккаунт должен быть пустым и страшно защищённым.
Правда пока сам Амазон не способствует такой реализации - отдельные сервисы (#CloudTrail, #Config, #SSO и др.) до сих пор завязаны некоторым своим функционалом на использование именно мастера. В результате для соблюдения архитектурной чистоты приходится плодить костыли и с нетерпением ждать, когда же эти косяки будут исправлены.
Однако делать нужно правильно, несмотря на некоторые текущие моменты. Как минимум знать и стремиться.
Здесь и далее всё будет подразумевать использование AWS #Organizations, что и есть реализация #multi_account_strategy.
===
Рекомендуемая схема
===
В рекомендуемой схеме мастер аккаунт пустой (с поправкой на то, что пока ещё требует запуска в нём) - как минимум, никакие виртуалки в нём точно не запускаем, а наш #devops становится суб-аккаунтом и смещается по иерархии ниже.
Для различных функций, в том числе связанных со всей организацией, некоторая часть мух из предыдущей "мухо-котлетной" схемы выделяются в отдельный аккаунт с расплывчатым названием Secure. Туда переезжают ключи шифрования, домены (только регистрации, а не Hosted zones), бэкапы, #CloudTrail-логи и прочие сущности с особой важностью для организации в целом.
Современные фичи Амазона изменяют некоторые архитектурные элементы.
• Bastion выбрасываем - появление #SSM #Session_Manager закрывает его функционал.
• Для #VPC_peering используем #Transit_Gateway.
• В Devops-аккаунте добаляется #Shared_VPC, которая используется для окружений без жёстких требований по безопасности (условно dev-test), хотя, в принципе, можно и для всех окружений.
Также в Devops-аккаунте появился #Jenkins как CI-инструмент - это может быть любой другой вам привычный (я же использую Jenkins, как говорил Портос, потому, что я использую Jenkins).
5 801
С учётом AWS #Organizations минимальная схема принимает вид, где есть мастер (root) аккаунт (помеченный ранее как #devops) и подаккаунты с окружениями.
Некоторые AWS сервисы до сих пор рассчитаны на работу именно из мастер-аккаунта, в том числе поэтому реализовывать #мультиаккаунт по такой схеме проще всего.
5 801
#single_account vs #multi_account_strategy
Споры о преимуществах той или иной стратегии ("всё/все в одном" или #мультиаккаунт) бессмысленны. Не буду хохмить про то, что они очень часто ведутся между теми, кто уже давно ест апельсины и теми, кто никогда их не пробовал, но не одобряет. Если максимально коротко - у каждого способа есть набор очевидных и неочевидных плюсов и минусов, однако #multi_account_strategy — суть современный способ работы современного проекта, а потому ориентироваться нужно именно на него.
Объять столь большую и радикально отличающуюся тему быстро невозможно, потому буду разбирать поэтапно, усложняя и объясняя по ходу.
===
Минимальная схема
===
Это классическая и общепринятая пару лет назад схема разделения — простая и понятная, с неё удобно начинать (как и я когда-то), условно для небольшой команды с одним проектом и одним девопсом.
По принципу разбиения схему можно назвать "мухи и котлеты". Всё, что не относится к поднимаемым окружениям - это условный Devops аккаунт. Окружения dev-stg-prod (test, etc) поднимаются единым образом, т.е. условно из одного шаблона и лишь с разными настройками.
Окружения живут в своих VPC и соединяются с Management VPC с помощью VPC peering. Доступ к закрытым ресурсам (без внешних айпишников) происходит через промежуточный Bastion инстанс.
Всё необходимое для поднятия окружений, различные ресурсы и настройки - всё лежит в Devops аккаунте, куда может иметь доступ лишь девопс, а разработчики ходят в dev-окружение и им выделяется доступ (временно, для деплоя) в stage-prod-etc.
Это (относительно) просто в реализации и поддержке, схема удовлетворяет требованиям различных #compliance (например, #NIST) и наверняка подойдёт для многих проектов, особенно тех, кто хочет начать использовать мультиаккаунты.
5 801
Если в #user_data переменных нужно получить #ImportValue параметры, то используется следующая конструкция:
UserData:
Fn::Base64: !Sub
- |
#!/bin/bash -x
## ...
echo "role_arn = ${CodeCommitRoleArn}" >> $AWS_CONFIG
## ...
#### end of UserData
- AwsAccountDevops: !ImportValue AwsAccountDevops
CodeCommitRoleArn: !ImportValue CodeCommitRoleArn
Т.е. передаём в Fn::Base64: !Sub массив, где сначала сам код, а потом список используемых в нём переменных (именно в таком порядке - код, затем переменные).5 801
Доступ в #CodeCommit (git репозиторий) можно получить не только через привычные логин-пароль (https) и ключ (ssh), но и с помощью IAM роли. Это удобно и безопасно, т.к. нет #credentials (лишь прикреплённая к инстансу роль). В качестве адреса репозитория при этом используется https-вариант.
Когда CodeCommit-репозиторий в том же аккаунте, то всё работает очевидно. Однако что делать, если согласно #multi_account_strategy какое-то test-окружение, поднятое в своём test-аккаунте, должно загрузить репозиторий из репозитория, расположенного в (другом) devops-аккаунте?
Тут потребуется подправить настройки credential.helper - чтобы #git сам переключался в нужный аккаунт.
git config --global credential.helper '!aws codecommit --profile devops-codecommit credential-helper $@'
То есть для этого используем описанный в предыдущем посте метод.
Вот полный пример кода для #user_data с загрузкой git из другого аккаунта:
## Setup Git for CodeCommit
mkdir /root/.aws
AWS_CONFIG=/root/.aws/config
echo "[profile devops-codecommit]" > $AWS_CONFIG
echo "credential_source = Ec2InstanceMetadata" >> $AWS_CONFIG
echo "role_arn = ${CodeCommitRoleArn}" >> $AWS_CONFIG
export HOME=/root
git config --global credential.helper '!aws codecommit --profile devops-codecommit credential-helper $@'
git config --global credential.UseHttpPath true
## get repos from CodeCommit
HTTPS_GIT=https://git-codecommit.us-east-1.amazonaws.com/v1/repos
git clone -b ${ProjectBranch} --quiet $HTTPS_GIT/${ProjectName} $DOCKERPROJECT_DIR &> /dev/null
https://docs.aws.amazon.com/codecommit/latest/userguide/auth-and-access-control.html5 801
Чтобы запустить #aws_cli команду для другого аккаунта, нужно сначала добавить в ~/.aws/config профиль типа:
[profile devops-codecommit] role_arn = arn:aws:iam::123456789012:role/codecommit-role credential_source = Ec2InstanceMetadataПараметры: devops-codecommit - просто имя профиля role_arn - роль в аккаунте, куда нужно переключиться credential_source = Ec2InstanceMetadata означает, что #IAM из роли инстанса У codecommit-role должны быть права на переключение "sts:AssumeRole" и остальное нужное (в данном примере - доступ в #CodeCommit). Теперь для просмотра репозиториев в другом аккаунте отработает следующая команда:
aws codecommit list-repositories --profile devops-codecommit
Т.е. благодаря флажку --profile происходит переключение в роль нужного аккаунта.
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html5 801
О вреде юзеров.
В грамотно спроектированном окружении нет (не должно быть) #IAM юзеров. Почему? Потому что у юзера есть #credentials и они должны быть где-то явно указаны (в отличие от роли, прикреплённой к инстансу).
Если у вас один аккаунт на всех и всё, значит все пользователи заходят через юзеров, что проблема в степени количества этих юзеров. Обязательно включайте MFA для всех юзеров. А лучше переходите на светлую сторону #multi_account_strategy + #SSO.
В легаси-проектах, где ПО не умеет роль (требует наличия AccessKeyId и SecretAccessKey) - приходится заводить юзера. Включайте ему минимальные права - ровно на то, что он должен делать.
Для некоторых ситуаций, например, доступ в #CodeCommit по SSH или в #ES вне #VPC - тоже требуется наличие юзера. Всё это издержки Амазона (фу, как не стыдно), не придумавшего пока, как реализовать это без юзеров.
Во всех остальных случаях - никаких юзеров. Помните, хороший юзер - это роль.
#recomendation
5 801
Некоторые #читы, полезные на местности (в виртуалке).
===
Получить список имеющихся (в нужном регионе) #KeyPair:
aws --region us-east-1 ec2 describe-key-pairs --query KeyPairs[].KeyName[]
===
Получить список #IAM ролей:
aws iam list-roles --query Roles[].Arn[]
===
Получить список юзеров:
aws iam list-users --query Users[].Arn[]
===
Получить детальный отчёт по правам юзеров:
aws iam get-account-authorization-details --query UserDetailList[]
#aws_cli
Уже доступно! Исследование Telegram 2025 — ключевые инсайты года 
