NAT Instance. Часть 2 — Auto Scaling group

Пришло время продолжить предыдущую статью о NAT Instance. В прошлый раз мы остановились на том, что создали объект VPC, настроили подсети и конечно же само окружение. Ну а теперь пора переходить к настройке Auto Scaling group, разрешений IAM и конечно же Security groups, чтобы разрешить EC2-инстансам выходить наружу. Обязательно загляните в первую статью в раздел подготовки окружения. Оно понадобится нам сейчас.

Напомню, что всю конфигурацию мы храним в Terraform, вопросы настройки через веб-интерфейс AWS затрагиваться не будут.

NAT Instance. Часть 2 — Auto Scaling group

Из первой статьи напомню, что структура каталога выглядит следующим образом. Как и ранее, по мере повествования буду выкладывать и объяснять содержимое каждого файла.

Итак, приступим.

Auto Scaling group

Все необходимые объекты мы создаем в файле vpc_nat_instance.tf, вот его содержимое:

По очереди разберем основные моменты.

template_file

Это ни что иное, как sh-скрипт, который будет выполнен при запуске инстанса. Вот содержимое файла user_data_nat_instance.sh:

Чтобы инстанс мог пересылать пакеты от машин в приватной сети наружу и обратно, нужно отключить у него атрибут SrcDestCheck 1. К сожалению, ресурс aws_launch_template 2 не позволяет 3 это сделать напрямую и пришлось искать обходные пути. Один из таких путей – смена нужного атрибута самим инстансом, что мы и реализуем в этом скрипте.

Примечание: есть некоторые подводные камни в этом способе, которые связаны с разрешениями на изменение собственных атрибутов. Об этом подробнее в главе IAM.

Идея скрипта в том, что вы сначала должны получить токен для авторизации, а потом сходить с этим токеном и поменять атрибут инстанса.

aws_network_interface

Ресурс создает тот самый интерфейс, о котором мы говорили в прошлой статье. Напомню, что трафик будет ходить как раз через этот интерфейс, который будет прикрепляться к EC2-инстанусу, созданному с помощью Auto Scaling group.

Стоит отметить, что навешивать Security Groups нужно именно на этот интерфейс, но не на Launch Template внутри секции network_interfaces, что могло бы показаться более логичным. В противном случае столкнетесь с подобными ошибками:

У модуля aws_network_interface 4 есть атрибут source_dest_check, который по аналогии с EC2-инстансом надо выставить в значение False (Default true).

aws_launch_template

Ключевой ресурс во всей нашей схеме, именно в нем описывается вся конфигурация будущих инстансов. Несмотря на это, рассказать что-то особенного о нем не получится. В нем просто объединяются все другие объекты, которые мы так старательно описываем в других участках конфигурации.

В секции network_interfaces как раз подключается сетевой интерфейс, а в iam_instance_profile – IAM-профиль для предоставления разрешений, необходимых инстансу для самостоятельного изменения нужного атрибута.

IAM

Ну а теперь подробнее о разрешениях. Дело в том, что по умолчанию сам инстанс не имеет прав на изменение своих же атрибутов. Это было бы уязвимостью. Потому нам надо предоставить ему разрешения в явном виде. Именно это и описывается в файле iam.tf:

Специфика IAM в том, что сначала надо создать политику assume role, которая предоставляет объекту право на принятие роли.

Примечание: звучит странно, но суть в том, что сервису EC2 нужно предоставить право на то, чтобы он взял на себя нужную роль. Подробнее изучить этот момент можно в документации – AssumeRole.

Делается это с помощью обязательной опции assume_role_policy у ресурса aws_iam_role. Далее просто прикрепляем нужную политику, которая предоставляет право ec2:ModifyInstanceAttribute. Ну а в довесок создаем aws_iam_instance_profile, который уже прикрепляем к aws_launch_template.

Security groups

Нам понадобятся две группы безопасности. Первая нужна для самого NAT-инстанса, чтобы разрешить ему принимать трафик из локальной сети и отправлять данные. Вторая группа предназначена для EC2-инстансов, находящихся в приватных сетях.

Примечание: добавьте дополнительные правила, если вдруг вам это потребуется. Например будет полезно открыть icmp для внутренних коммуникаций.

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

Заключение

В текущем состоянии все должно работать, остается только выполнить terrafom init && terraform apply. Тем не менее важно знать о недостатках этой схемы. Нюанс в том, что я размещаю целевые инстансы в разных зонах доступности, а NAT-инстанс у меня всего один и располагаться он может разумеется только в одной зоне доступности. Таким образом, трафик будет гоняться между зонами доступности одного региона, а это стоит дополнительных денег, что явно упоминается в документации 5:

Data transferred “in” to and “out” from Amazon EC2, Amazon RDS, Amazon Redshift, Amazon DynamoDB Accelerator (DAX), and Amazon ElastiCache instances, Elastic Network Interfaces or VPC Peering connections across Availability Zones in the same AWS Region is charged at $0.01/GB in each direction.

А вот что пишут на счет трафика внутри зоны доступности:

Data transferred between Amazon EC2, Amazon RDS, Amazon Redshift, Amazon ElastiCache instances, and Elastic Network Interfaces in the same Availability Zone is free.

Если хотите сделать схему дешевле, то разумно будет создать по одной ASG с NAT-инстансом в каждой зоне доступности. Другое дело, что сами EC2-инстансы тоже стоят денег и еще непонятно что в итоге будет дешевле – оплачивать cross-AZ трафик или дополнительный NAT-инстанс. Решать вам, а у меня на этом все. Успехов!

Яндекс.Метрика