ch
Feedback
AWS Notes

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 801
订阅者
-324 小时
-67
-730
帖子存档
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 параметры, передавая переменные через них.

Безопасности пост.
Безопасности пост.

Просто оставлю это здесь - интересная утилита, реализующая traffic mirroring: https://github.com/buger/goreplay Кому интересно, чуть расшифрую (не про Амазон). Тестирование почти всегда проводится какими-то искусственными паттернами, которые должны при это дать некую гарантию, что на проде при реальной нагрузке оно не поломается. А метод traffic mirroring (или shadow traffic) дублирует реальный трафик, пришедший на прод в нужное вам (тестовое) окружение. Это очень круто - иметь возможность тестировать "живым" трафиком. Модная тема, особенно легко реализуемая с помощью #kubernetes, так что советую как минимум знать про это - сие есть следующая инкарнация подходов Blue/Green или Canary Deployment.

Если у вас годами себе мирно жили тучи файлов на #s3 и вдруг выясняется, что по #compliance причинам теперь их всех нужно зашифровать либо по требованиями аудита требуется всем проставить (переставить) тэги или ещё какая-то глобально-массовая напасть — для всех таких работ теперь есть нативный инструмент #s3_batch_operations: https://aws.amazon.com/blogs/aws/new-amazon-s3-batch-operations/

Сам я не пользуюсь врапперами/генераторами для #CloudFormation типа Stacker или Troposphere, однако для любителей такого подхода есть ещё одна полезная утилитка Sceptre: https://github.com/cloudreach/sceptre

Ещё один ресурс для возможности сравнения EC2 инстансов - с некоторыми претензиями на мобильную версию: https://cloudbanshee.com/ec2 Кстати, кто активно пользуется https://ec2instances.info и кому чего-то там не хватает — может вполне такое сделать сам: https://github.com/powdahound/ec2instances.info #info #comparison

Поддержка 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.

При создании #security_group в #CloudFormation #templates не забывайте (не ленитесь) прописать Description в ингрессах (в каж
При создании #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: cadvisor

В пандан к предыдущему посту - заслуживающая внимания утилита для вычисления минимально нужных #IAM привилегий посредством сравнения имеющихся политик у юзера/роли и тех, что реально запрашиваются через AWS API (определяется с помощью #CloudTrail логов). Может особенно может быть полезной для адептов #single_account, где такое весьма актуально в каждодневной борьбе с желающими урвать себе прав и побольше. С помощью утилиты CloudTracker можно чётко контролировать используемое: кто не оценил вашу доброту - отобрать лишнее, а всем остальным выдавать доступ строго по талонам. https://github.com/duo-labs/cloudtracker

Не все йогурты одинаково полезны, а потому с Managed #IAM политиками нужно быть на чеку (амазоновцы не парятся и ставят "с запасом" - многие имеют излишние права). Чтобы знать врага в лицо, добрые люди собрали коллекцию IAM Managed политик и ведут историю их изменений: https://github.com/SummitRoute/aws_managed_policies/tree/master/policies

Дальнейшее усложнение 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 и/или личные аккаунты для разработчиков. И так далее и тому подобное — основные типы уже были перечислены и это уже лишь детали.

Минимальная схема не является рекомендованной, т.к. поднятие ресурсов в мастер-аккаунте не есть #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).

С учётом AWS #Organizations минимальная схема принимает вид, где есть мастер (root) аккаунт (помеченный ранее как #devops) и
С учётом AWS #Organizations минимальная схема принимает вид, где есть мастер (root) аккаунт (помеченный ранее как #devops) и подаккаунты с окружениями. Некоторые AWS сервисы до сих пор рассчитаны на работу именно из мастер-аккаунта, в том числе поэтому реализовывать #мультиаккаунт по такой схеме проще всего.

#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) и наверняка подойдёт для многих проектов, особенно тех, кто хочет начать использовать мультиаккаунты.

Если в #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 массив, где сначала сам код, а потом список используемых в нём переменных (именно в таком порядке - код, затем переменные).

Доступ в #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.html

Чтобы запустить #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.html

Когда увидел, что на проекте 62 юзера.

О вреде юзеров. В грамотно спроектированном окружении нет (не должно быть) #IAM юзеров. Почему? Потому что у юзера есть #credentials и они должны быть где-то явно указаны (в отличие от роли, прикреплённой к инстансу). Если у вас один аккаунт на всех и всё, значит все пользователи заходят через юзеров, что проблема в степени количества этих юзеров. Обязательно включайте MFA для всех юзеров. А лучше переходите на светлую сторону #multi_account_strategy + #SSO. В легаси-проектах, где ПО не умеет роль (требует наличия AccessKeyId и SecretAccessKey) - приходится заводить юзера. Включайте ему минимальные права - ровно на то, что он должен делать. Для некоторых ситуаций, например, доступ в #CodeCommit по SSH или в #ES вне #VPC - тоже требуется наличие юзера. Всё это издержки Амазона (фу, как не стыдно), не придумавшего пока, как реализовать это без юзеров. Во всех остальных случаях - никаких юзеров. Помните, хороший юзер - это роль. #recomendation

Некоторые #читы, полезные на местности (в виртуалке). === Получить список имеющихся (в нужном регионе) #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