Amazon EC2 как сервис вычислений или виртуальных машин, предоставляемый Amazon Web Services (AWS), может быть одним из распространенных сервисов, которые мы используем ежедневно.

Тип использования EC2 может быть разным. Его можно использовать как бэкэнд для контейнерных сервисов, таких как ECS, его можно использовать как экземпляр базы данных, действовать как сервер приложений, использовать как хост-бастион / хост-прыжок и т. Д.

В повседневной производственной среде мы также можем получить доступ к другим ресурсам или сервисам AWS из EC2. Например: загрузка файлов из экземпляра EC2 в S3 с помощью AWS CLI и многих других действий. Чтобы использовать эту функцию, нам необходимо ввести учетные данные AWS, такие как AWS Access Key и AWS Secret Key. И эти учетные данные могут быть введены или сохранены в экземпляре EC2.

Из варианта использования, о котором я упоминал выше, мы можем столкнуться с другими потенциальными проблемами. Поскольку ключ доступа AWS и секретный ключ AWS вводятся или сохраняются в инстансе EC2, это создает потенциальную угрозу безопасности для любого анонимного или любого непривилегированного человека, который может получить или прочитать эти учетные данные. Из-за этой проблемы безопасности это анонимное или непривилегированное лицо может запускать службы или ресурсы в нашей учетной записи AWS без нашего разрешения.

Кроме того, мы можем столкнуться с другой проблемой. Если количество экземпляров EC2, которым требуется доступ к другим ресурсам или службам, достаточно, нам необходимо ввести или настроить эти учетные данные по одному или для каждого экземпляра. Это занятие должно быть утомительным.

Чтобы решить эту проблему, AWS предоставила альтернативу, если нашему EC2 потребуется доступ к другим ресурсам или сервисам. Мы можем настроить наш EC2 с ролью EC2 IAM или иногда его также называют профилем экземпляра IAM.

Благодаря роли EC2 IAM нам не нужно вводить или настраивать конфиденциальные учетные данные для нашего экземпляра EC2, которые могут вызвать проблемы с безопасностью. Что нам нужно сделать, так это создать роль IAM, и эта роль IAM будет связана с экземпляром EC2. Роль IAM также будет связана с некоторыми политиками IAM, которые будут контролировать привилегии экземпляра EC2.

В основном, чтобы настроить роль EC2 IAM или роль IAM как общую, мы можем настроить ее через веб-консоль или с помощью программного доступа, такого как инфраструктура как код.

В этой статье я объясню более подробно с точки зрения инфраструктуры как кода (IaC). Таким образом, все настройки будут выполняться с использованием инструмента IaC.

Сценарий, который я использовал в этой статье, заключается в том, что я настрою профиль роли EC2 IAM / IAM Instance Profile, который будет связан с экземпляром EC2. Тогда роль IAM также будет связана с политиками IAM.

В этой статье я использую AWS Managed Policy. После объявления роли EC2 IAM, роль IAM будет связана с экземпляром EC2, который будет работать с операционной системой Ubuntu 20.04. Конфигурации определяются с помощью Terraform, а метод использует интерфейс командной строки Terraform.

Если вам интересно узнать основы Terraform CLI, вы с удовольствием ознакомитесь с другим моим постом, в котором обсуждалась эта тема, по этой ссылке: https://aws.plainenglish.io/provision-amazon-ec2-using-terraform-cli-d86ab78ee217

Предпосылки

Перед началом настройки необходимо подготовить несколько компонентов, таких как:

  • Установленный интерфейс командной строки Terraform. Для установки, пожалуйста, обратитесь: https://learn.hashicorp.com/tutorials/terraform/install-cli
  • Ключ доступа AWS, секретный ключ доступа, профиль (может быть профилем по умолчанию или именованным профилем), который был настроен через интерфейс командной строки AWS. Обратитесь к этому руководству для справки: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html. Этот ключ доступа AWS и секретный ключ доступа будут использоваться в качестве учетных данных для Terraform в нашем локальном блокноте, чтобы Terraform мог получить доступ к API на AWS и создавать сервисы из кода.

Конфигурация

В этой статье роль EC2 IAM будет объявлена ​​как модуль (локальный модуль Terraform), затем модуль будет вызываться в основном коде EC2. Цель состоит в том, чтобы получить большую гибкость, роль IAM с разными политиками может быть связана со многими EC2 с разными потребностями.

Ниже представлена ​​структура каталогов:

ec2/
├─ main.tf
├─ outputs.tf
├─ user-data.sh
├─ variables.tf
modules/
├─ iam/
      ├─ iam_roles.tf
      ├─ outputs.tf
      ├─ variables.tf

Вот шаги настройки:

  1. Конфигурация начинается с создания локального модуля терраформирования для IAM. Первым обсуждаемым файлом будет /module/iam/iam_roles.tf.

В этом файле мы начинаем с создания или генерации политики IAM для данных, у которой есть доступ sts: AssumeRole к EC2.

# Generate assume role policy
 data "aws_iam_policy_document" "ec2-assume-role" {
   statement {
     actions = ["sts:AssumeRole"]

     principals {
       type        = "Service"
       identifiers = ["ec2.amazonaws.com"]
     }
   }
 }

После этого мы создаем профиль экземпляра IAM, роль которого относится к роли IAM с тем же именем «ludes-ec2-admin-role».

В ресурсе роли IAM «ludes-ec2-admin-role» я объявил имя, путь и предполагаемую роль, которые относятся к политике IAM данных документа выше.

Позже эти данные будут преобразованы в формат json. Следующая политика IAM, которая будет прикреплена или использована ролью IAM, - это AWS Managed Policy. Все эти параметры будут относиться к переменным, которые были объявлены в /module/iam/variables.tf.

# Configure IAM instance profile
 resource "aws_iam_instance_profile" "ludes-ec2-admin-role" {
   name = var.iam-role-name
   role = aws_iam_role.ludes-ec2-admin-role.name
 }
 # Configure IAM role
 resource "aws_iam_role" "ludes-ec2-admin-role" {
   name                  = var.iam-role-name
   path                  = var.iam-role-path
   assume_role_policy    = data.aws_iam_policy_document.ec2-assume-role.json
   managed_policy_arns   = var.iam-role-policy-attachment
 }

2. Следующий файл, который будет обсуждаться, - это /modules/iam/variables.tf.

В этом файле я объявил все переменные, которые использовались в /modules/iam/iam_roles.tf.

Переменная iam-role-name используется для присвоения имени роли IAM, переменная iam-role-path используется для объявления пути, используемого ролью IAM.

Затем переменная iam-role-policy-attachment используется для объявления AWS Managed Policy, связанной с ролью IAM.

В этой статье я использую AmazonEC2FullAccess и AmazonS3FullAccess только в демонстрационных целях. В производственной среде имейте в виду, что вы должны использовать политику с наименьшими привилегиями, чтобы предотвратить брешь / проблему в безопасности.

# Define role name
 variable "iam-role-name" {
   type        = string
   description = "IAM role name"
   default     = "ludes-ec2-admin-role"
 }

 # Define role path
 variable "iam-role-path" {
   type        = string
   description = "IAM role path"
   default     = "/"
 }

 # Define Policy. Policy consist list of AWS managed polices
 variable "iam-role-policy-attachment" {
   type        = list(string)
   description = "List of IAM policies"
   default     = [
                   "arn:aws:iam::aws:policy/AmazonEC2FullAccess",
                   "arn:aws:iam::aws:policy/AmazonS3FullAccess" 
                 ] 
 }

3. Следующий файл, который будет обсуждаться, - это /modules/iam/outputs.tf.

В этом файле я объявил 1 вывод с именем iam-instance-profile-name. Этот вывод будет запрашивать профиль экземпляра iam в качестве вывода. И этот вывод будет использоваться как ссылка в ec2 main.tf.

# Generate output of IAM role name
 output "iam-instance-profile-name" {
   value       = aws_iam_instance_profile.ludes-ec2-admin-role.name
   description = "IAM role name"
 }

4. Следующий файл, который мы обсудим, - это /ec2/main.tf. Папка EC2 будет действовать как корневой модуль и будет использовать папку / modules / iam как ссылку на дочерний модуль.

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

# Setup terraform provider(s) and version
 terraform {
   required_providers {
     aws = {
       source  = "hashicorp/aws"
       version = "3.53.0" # Please change version that will be used here
     }
     template = {
       source = "hashicorp/template"
       version = "2.2.0" # Please change version that will be used here
     }
   }
 }

 # Setup aws region and credentials
 provider "aws" {
   region                  = "ap-southeast-1"
   shared_credentials_file = var.aws_credential_file
   profile                 = var.aws_credential_profile
 }

5. По-прежнему в том же файле /ec2/main.tf, следующим шагом мы объявили некоторые ссылки, которые будут использоваться для создания ресурса EC2.

В этом разделе мы получим данные об AMI ID Ubuntu 20.04. Эта информация позже будет использоваться EC2 как AMI ID.

# Get latest public ubuntu AMI ID from Parameter Store in chosen region
 data "aws_ami" "ubuntu" {
   most_recent = true

   filter {
     name   = "name"
     values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
   }

   filter {
     name   = "virtualization-type"
     values = ["hvm"]
   }

   owners = ["099720109477"] # Canonical
 }

Затем мы объявляем шаблон файла пользовательских данных, который будет ссылаться на файл /ec2/user-data.sh. Этот файл будет использоваться в качестве сценария запуска или данных пользователя EC2 при загрузке EC2.

# Reference for EC2 user-data
 data "template_file" "user-data" {
   template = "${file("./user-data.sh")}"
 }

Затем мы объявляем используемый дочерний модуль. В этой статье я буду ссылаться на модуль instance_profile с источником из / modules / iam /.

module "instance_profile" {
   source = "../modules/iam/"
 }

6. Все еще в файле /ec2/main.tf. Я объявляю экземпляр ресурса EC2 с именем «ludes-ubuntu-0». Для AMI ID будут ссылаться на данные, как мы обсуждали выше, которые получат AMI ID Ubuntu 20.04.

В качестве пары ключей я использую существующую пару ключей, которая была сгенерирована и сохранена на AWS. Затем EC2 получит пользовательские данные из файла шаблона user_data, о котором говорилось выше. Профиль экземпляра IAM будет ссылаться на дочерний модуль, который был объявлен, и будет использовать имя профиля экземпляра в качестве ссылки. Это результат, объявленный в / modules / iam / output / tf. Другие вещи, такие как тип экземпляра, размер тома, будут использовать переменные, которые были объявлены в /ec2/variables.tf.

# Setup EC2 instance using ubuntu AMI
 resource "aws_instance" "ludes-ubuntu-0" {
   ami                         = data.aws_ami.ubuntu.id
   instance_type               = var.ec2_instance_type
   associate_public_ip_address = true
   key_name                    = "ludes-key-demo-0"
   user_data                   = data.template_file.user-data.rendered
   iam_instance_profile        = module.instance_profile.iam-instance- 
profile-name

   root_block_device {
     volume_size = var.ec2_volume_size
   }

   tags = {
     Name = "ludes-ubuntu-0" # Please change name tag here
   }

   depends_on = [
     module.instance_profile.iam-instance-profile-name
   ]
 }

7. Следующий файл, который мы обсудим, - это /ec2/user-data.sh. В этом файле я объявил сценарий запуска для начальной загрузки EC2, и он установит AWS CLI.

#!/bin/bash

 # Shell script to install aws cli from user data when bootstapping ec2
 # Script will run on user ubuntu
 # Might need to relogin before aws cli can fully functional or you can issued command aws --version to verify
 sudo -u ubuntu
 sudo apt-get update
 sudo apt-get install -y unzip
 curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
 unzip awscliv2.zip
 sudo ./aws/install

8. Следующий файл, который мы обсудим, - это /ec2/variables.tf. В этом файле я объявил переменную «aws_credential_file», которая будет использоваться в качестве ссылки, где расположение учетных данных aws и переменная «aws_credential_profile» будет относиться к используемому именованному профилю, которым в этой статье является «ludes-terraform-admin». Помимо этого, я объявил переменную «ec2_instance_type», которая будет ссылаться на тип экземпляра ec2, и «ec2_volume_size» для определения размера тома EBS, используемого EC2.

# Define path to aws credentials file
 variable "aws_credential_file" {
   type        = string
   description = "Path to aws credentials file"
   default     = "~/.aws/credentials"
 }

 # Define aws profile
 variable "aws_credential_profile" {
   type        = string
   description = "AWS profile used for provision services"
   default     = "ludes-terraform-admin"
 }

 # Define EC2 instance type
 variable "ec2_instance_type" {
   type        = string
   description = "Amazon EC2 instance type"
   default     = "t2.micro" # Please change ec2 instance type here
 }

 # Define EC2 instance volume size
 variable "ec2_volume_size" {
   type        = number
   description = "Amazon EC2 instance volume size"
   default     = 10 # Please change ec2 root volume size here
 }

9. Последний файл, который будет обсуждаться, - это /ec2/outputs.tf. В этом файле я объявил вывод с именем «ec2_public_ip». Этот вывод будет отображать общедоступный IP-адрес EC2. И этот вывод будет отображаться после завершения применения terraform.

# Generate output of EC2 public IP
 output "ec2_public_ip" {
   value       = aws_instance.ludes-ubuntu-0.public_ip
   description = "Public IP of EC2 instance"
 }

10. После завершения настройки кода terraform мы запускаем этот код с помощью terraform init из терминала или интерфейса командной строки.

11. Мы также можем проверить, действительны ли коды, выполнив команду terraform validate.

12. После инициализации и проверки. Затем мы можем запустить terraform plan, чтобы узнать, какие ресурсы будут созданы.

Поскольку я объявил вывод, этот план также будет информировать о том, что есть вывод, который будет отображаться после применения.

13. Если план был отображен, как ожидалось, мы можем запустить Terraform apply, чтобы terraform начал предоставлять ресурсы / сервисы на AWS.

Подождите, пока завершится подача заявки на Terraform. И после этого мы увидим публичный IP EC2.

14. Затем мы можем проверить подключение к EC2, используя SSH, к общедоступному IP-адресу, который отображается в выводе terraform.

15. Убедитесь, что SSH для Ubuntu EC2 успешно. Также убедитесь, что AWS CLI установлен.

16. До этого момента у нас есть доказательство того, что terraform был успешно создан инстансом EC2. Мы также можем проверить это с помощью веб-консоли AWS. Также убедитесь, что роль IAM была успешно создана.

17. Затем мы можем проверить, правильно ли работает профиль роли EC2 IAM / IAM Instance Profile. Поскольку в этой статье я заявил, что ассоциирует политику AmazonEC2FullAccess, мы можем попытаться перечислить или описать экземпляр EC2 из AWS CLI на Ubuntu EC2.

18. Чтобы убедиться, что политика AmazonS3FullAccess также работает правильно, я создал корзину S3 с именем «ludes-demo-bucket-0».

19. Затем мы проверяем, запустив команду list s3 bucket из интерфейса командной строки AWS в Ubuntu EC2.

Заключение

Итак, мы подошли к концу этой статьи. В этой статье мы обсудили, как создать профиль роли EC2 IAM / IAM Instance Profile с помощью инструмента IaC, которым является Terraform. Затем с экземпляром EC2 связывается роль EC2 IAM. Мы также проверяем, может ли экземпляр EC2 запускать команду AWS CLI, разрешения которой предоставлены ролью EC2 IAM.

Если вы хотите проверить исходный код, вы также можете посетить мой GitHub по этому адресу: https://github.com/lanandra/terraform-template-aws

Если у вас есть комментарии, критика или предложения, отправьте их в раздел комментариев.

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

tl;dr

Настройте EC2 IAM Role / IAM Instance Profile с помощью IaC Tool (Terraform).

Больше контента на plainenglish.io