Эпический провайдер AWS Terraform для вашей инфраструктуры Amazon

Если вы планируете управлять и работать с Amazon Web Services (AWS), использование Terraform AWS провайдера обязательно. Он позволяет взаимодействовать со множеством ресурсов, поддерживаемых AWS, таких как Amazon S3, Elastic Beanstalk, Lambda и многих других.

В этом исчерпывающем руководстве вы узнаете, шаг за шагом, практически все, что вам нужно знать о провайдере AWS и о том, как использовать этот провайдер с помощью Terraform для управления вашей инфраструктурой Amazon.

Давайте начнем!

Предварительные требования

Если вы хотите следовать этому руководству, убедитесь, что у вас есть следующее:

  • A code editor – Even though you can use any text editor to work with Terraform configuration files, you should have one that understands the HCL Terraform language. Try out Visual Studio (VS) Code.

Что такое Terraform AWS Provider?

Terraform зависит от плагинов для взаимодействия с облачными провайдерами, такими как AWS, Google Cloud Platform (GCP) и Oracle. Один из самых широко используемых провайдеров – провайдер AWS. Этот провайдер взаимодействует с множеством ресурсов, поддерживаемых AWS, таких как Amazon S3, Elastic Beanstalk, Lambda и многие другие.

Terraform использует провайдер AWS с правильными учетными данными для подключения к Amazon и управления или развертывания/обновления десятков сервисов AWS.

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

Объявление провайдера AWS

При необходимости ссылаться на имя поставщика нужно определить локальное имя. Локальное имя – это имя поставщика, которое присваивается внутри блока required_providers. Локальные имена присваиваются при требовании поставщика и должны быть уникальными для каждого модуля.

При объявлении required_providers также необходимо объявить параметр source в Terraform 0.13 и более поздних версиях. Параметр source задает адрес источника, откуда Terraform может загрузить плагины.

Адреса источников состоят из трех частей:

  • Имя хоста – имя хоста реестра Terraform, распространяющего поставщика. Имя хоста по умолчанию – registry.terraform.io.
  • Пространство имен – организационное пространство имен в указанном реестре.
  • Тип – это краткое имя, которое вы указываете для платформы или системы, которой управляет поставщик, и оно должно быть уникальным.

Ниже вы можете увидеть синтаксис объявления параметра source, где три части адреса источника разделены слэшами (/).

## <HOSTNAME>/]<NAMESPACE>/<TYPE>

# ПРИМЕР ИСПОЛЬЗОВАНИЯ СИНТАКСИСА ПАРАМЕТРА ИСТОЧНИКА

# Объявление местоположения/адреса источника, откуда Terraform может загружать плагины
# Официальный провайдер AWS принадлежит пространству имен hashicorp на 
# registry.terraform.io registry. Поэтому адрес источника hashicorp - hashicorp/aws
source  = "hashicorp/aws"

Теперь ниже приведена конфигурация Terraform, объявляющая требуемое имя провайдера (aws), вместе с адресом источника, версией провайдера AWS и настройкой региона провайдера (us-east-2).

# Объявление Требований Провайдера при установке Terraform 0.13 и позднее
terraform {
  # Требование провайдера состоит из локального имени (aws), 
  # местоположения источника и ограничения версии. 
  required_providers {
    aws = {     
      # Объявление местоположения/адреса источника, откуда Terraform может загружать плагины
      source  = "hashicorp/aws"
      # Объявление версии провайдера aws как более новой, чем 3.0
      version = "~> 3.0"  
    }
  }
}

# Настройка провайдера AWS в регионе us-east-2
provider "aws" {
  region = "us-east-2"
}

Аутентификация учетной записи AWS с жестко закодированными учетными данными

Теперь, когда у вас есть базовое понимание того, как объявить провайдера AWS, давайте рассмотрим, как аутентифицировать учетную запись AWS.

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

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

Приведенная ниже конфигурация объявляет локальное имя (aws) вместе с регионом провайдера (us-east-2), как показано ниже. Вы можете видеть, что блок провайдера AWS также объявляет ключ доступа и секретный ключ для аутентификации учетной записи AWS.

# Объявление провайдера AWS с именем aws
provider "aws" {
  # Объявление региона провайдера
  region = "us-east-2"
  # Объявление access_key и secret_key
  access_key = "access-key"
  secret_key = "secret-key"
}

Защита учетных данных с использованием переменных среды

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

Есть ли еще способ обеспечить безопасность учетных данных? Да, объявив их как переменные среды, нет ограничений на количество, которое вы можете объявить. Переменные среды – это переменные, значения которых устанавливаются вне файла конфигурации Terraform и состоят из пары имя/значение.

Запустите серию команд export ниже, чтобы экспортировать каждую переменную среды. Экспортирование переменных среды делает их доступными во всей программе или до тех пор, пока Terraform не выполнит команды.

# Экспорт переменной AWS_ACCESS_KEY_ID
export AWS_ACCESS_KEY_ID="access-key"
# Экспорт AWS_SECRET_ACCESS_KEY
export AWS_SECRET_ACCESS_KEY="secret-key"
# Экспорт AWS_DEFAULT_REGION
export AWS_DEFAULT_REGION="us-east-2"

Хранение нескольких учетных данных в именованном профиле

Как же сохранить множество учетных данных и использовать их при необходимости? Хранение учетных данных в именованном профиле – идеальный вариант.

Ниже приведен код, который создает именованный профиль (Мойпрофиль), содержащий ключ доступа и секретный ключ.

Именованные профили по умолчанию находятся в $HOME/.aws/credentials/Мойпрофиль на Linux и macOS, или %USERPROFILE%\.aws\credentials\Мойпрофиль на Windows. Замените Мойпрофиль на фактическое имя именованного профиля.

# Создание именованного профиля с именем 'Myprofile'
[Myprofile]
aws_access_key_id = AKIAVWOJMI5836154yRW31
aws_secret_accesss_key = vIaGmx2bJCAK90hQbpNhPV2k5wlW7JsVrP1bm9Ft

После создания именованного профиля в ~/.aws/credentials, вы можете ссылаться на этот профиль в конфигурации Terraform, используя атрибут profile. Ниже приведен пример ссылки на именованный профиль с именем Myprofile.

# Настройка провайдера AWS с именем 'aws' в регионе us-east-2
provider "aws" {
  region = "us-east-2"
  # Объявление именованного профиля (Myprofile)
  profile = "Myprofile"
}

Объявление Assume Role в провайдере AWS

Вы только что научились настраивать провайдер AWS, объявляя жестко закодированные учетные данные перед запуском Terraform. Но возможно, вы хотите объявить учетные данные во время выполнения. В этом случае вам нужен API AssumeRole. AssumeRole предоставляет временные учетные данные, содержащие идентификатор ключа доступа, секретный ключ доступа и маркер безопасности. Эти учетные данные позволяют вам подключаться к AWS.

Код ниже объявляет provider с именем aws и assume_role, который содержит имя роли и имя сеанса. Для настройки доступа AssumeRole вы должны определить IAM-роль, которая указывает привилегии, которые она предоставляет, и сущности, которые могут ее принять.

# Объявление Поставщика AWS с именем 'aws'
provider "aws" {
  # Объявление AssumeRole
  assume_role {
		# Объявление имени ресурса.
    # role_arn - это имя ресурса Amazon (ARN) роли IAM для предположения.
    # ARN - это уникальный номер, выровненный по всем ресурсам в учетной записи AWS.
    role_arn     = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
    # Объявление имени сеанса
    session_name = "SESSION_NAME"
  }
}

Объявление нескольких поставщиков AWS

На данный момент вы узнали, как объявить и настроить Поставщика AWS в Terraform, который работает с одним регионом. Но что, если вам нужно управлять вашей инфраструктурой или услугами AWS в нескольких областях облака? В этом случае вам потребуется объявить ключевое слово alias.

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

Приведенный ниже код объявляет поставщика AWS по умолчанию с именем aws с установленным region в us-east-2. А затем объявляет дополнительного поставщика AWS с тем же именем, но с объявленным alias с именем west и region установленным в us-west-2.

Объявление псевдонима `alias` позволяет создавать ресурсы по умолчанию в регионе us-east-2 или в регионе us-west-2, если выбран провайдер aws.west в зависимости от требований.

# Ресурсы конфигурации по умолчанию провайдера, начинающиеся с aws.
provider "aws" {
  # Объявление региона us-east-2 для провайдера AWS с именем 'aws'
  region = "us-east-2" 
}

# Дополнительная конфигурация провайдера для региона west. 
# Ресурсы могут ссылаться на это как на aws.west.
provider "aws" {
  alias  = "west"
  # Объявление региона us-west-2 для провайдера AWS, который ссылается как 'west'
  region = "us-west-2"
}

# Объявление ресурса с использованием дополнительного провайдера в регионе west
resource "aws_instance" "west-region" {
  # Объявление провайдера как aws.west
  # aws.west ссылается на провайдера AWS с именем 'aws' и с псевдонимом 'west'
  provider = aws.west
}

# Объявление ресурса с использованием провайдера по умолчанию
resource "aws_instance" "east-region" 
}

Настройка конфигурации конечной точки провайдера AWS

Настройка конечной точки удобна при подключении к нестандартным конечным точкам служб AWS, таким как AWS Snowball или при локальном тестировании.

Настройте провайдера AWS в Terraform для использования настроенных конечных точек. Сделайте это, объявив блок конфигурации endpoints внутри блока провайдера, как показано ниже.

Нижеприведенная конфигурация позволяет вам получить доступ к сервису AWS S3 на локальном порту 4572, как если бы вы фактически обращались к сервису AWS S3 в учетной записи AWS. Аналогично, конфигурация позволяет получить доступ к dynamodb локально на порту 4569. DynamoDB – это сервис NoSQL-баз данных, который обеспечивает быструю производительность с безболезненной масштабируемостью.

Проверьте список настроенных конечных точек, которые позволяет провайдер AWS Terraform.

# Объявление провайдера AWS с именем 'aws'
provider "aws" {
  # Объявление конечных точек
  endpoints { 
    # Объявление dynamodb на локальном хосте с портом 4569 
    dynamodb = "<http://localhost:4569>"  
    # Объявление S3 на локальном хосте с портом 4572
    s3 = "<http://localhost:4572>"  
  }
}

Добавление тегов

Ранее вы узнали, как объявляется провайдер AWS с конфигурациями, такими как регион, исходное расположение и т. д. Но для более эффективного управления вашими ресурсами вам необходимо добавить теги на уровне провайдера.

Теги – это ярлыки, состоящие из пользовательских ключей и значений. Теги удобны, когда вам нужно проверить выставление счетов, собственность, автоматизацию, управление доступом и многие другие случаи использования в учетной записи AWS.

Вместо добавления тегов ко всем ресурсам индивидуально давайте узнаем, как добавить теги ко всем ресурсам на уровне провайдера, что поможет сэкономить много кода и времени.

Ниже приведенный код настраивает провайдера AWS с тегами, определенными внутри default_tags. Преимущество добавления тегов внутри провайдера заключается в том, что указанные теги автоматически добавляются при создании любого ресурса с этим провайдером.

# Настройка провайдера AWS с именем 'aws'
provider "aws" {
  # Добавление тегов по умолчанию "Environment" и "Owner" на уровне провайдера
  default_tags {
    # Объявление значений тегов
    tags = {
      Environment = "Production"
      Owner       = "shanky"
    }
  }
}
# Создание ресурса 'aws_vpc' с тегом Name=MyVPC
resource "aws_vpc" "myinstance" {
  tags = {
    Name = "MyVPC"
  }
}

Игнорирование тегов

Включение тегов на уровне провайдера помогает применять теги по всей среде. Но иногда нужно игнорировать теги, например, если вы не хотите добавлять тег по умолчанию к экземпляру EC2 и предпочтете применить его к остальным ресурсам в учетной записи AWS. Давайте проверим!

Ниже приведенный код настраивает провайдера AWS с определенными для игнорирования тегами внутри провайдера. Преимущество использования тега игнорирования заключается в том, что он позволяет не добавлять теги по умолчанию к определенным ресурсам и применять их к остальным ресурсам.

В нижеприведенном коде, при создании любого ресурса с использованием поставщика aws, все ресурсы будут игнорировать теги LastScanned и kubernetes.io.

# Настройка поставщика AWS с именем aws
provider "aws" {
	# Игнорировать префиксы ключей и ключи тегов для всех ресурсов под поставщиком AWS (aws)
  ignore_tags {
    key_prefixes = ["kubernetes.io"]
  }
  ignore_tags {
    keys = ["LastScanned"]
  }
}

Создание корзины AWS S3

На данный момент вы изучили все о том, как объявлять и настраивать поставщиков AWS в глубину. Но простое объявление поставщика AWS ничего не делает, пока вы не управляете ресурсами AWS, такими как предоставление бакета AWS S3 или удаление экземпляра Ec2 и т. д. Итак, давайте узнаем, как создать бакет AWS S3!

1. Создайте папку с именем ~/terraform-s3-demo, затем измените (cd) рабочий каталог на эту папку. Папка ~/terraform-s3-demo будет содержать файл конфигурации и все связанные файлы, которые создаст Terraform.

mkdir ~/terraform-s3-demo
cd ~/terraform-s3-demo

2. Скопируйте и вставьте конфигурацию ниже в свой любимый редактор кода и сохраните ее как main.tf в каталоге ~/terraform-s3-demo.

Файл main.tf создает несколько необходимых ресурсов:

  • Требование к поставщику: Требование к поставщику состоит из локального имени, расположения источника и ограничения версии.
  • Ключ шифрования: Ключ шифрования Amazon S3 помогает в S3 ведре, чтобы все новые объекты были зашифрованы при хранении в ведре. Ключи шифрования создаются с использованием aws_kms_key в Terraform.
  • Настройка AWS Provider: Объявление имени провайдера (aws) вместе с регионом us-east-2.
  • Ведро: Этот модуль Terraform создает ведро с именем terraformdemobucket. Terraform не может удалить это ведро, так как оно содержит флаг force_destroy.

Версионность: Версионность в Amazon S3 означает хранение нескольких версий объекта в одном ведре

# Настройка провайдера AWS с именем aws
provider "aws" {
# Игнорировать префиксы ключей тегов и ключи для всех ресурсов под провайдером aws. 
  ignore_tags {
    key_prefixes = ["kubernetes.io/"]
  }
  ignore_tags {
    keys = ["LastScanned"]
  }
}

# Объявление требований к провайдеру
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

# Настройка провайдера AWS (aws) с регионом, установленным на 'us-east-2'
provider "aws" {
  region = "us-east-2"
}

# Предоставление доступа к ведру
resource "aws_s3_bucket_public_access_block" "publicaccess" {
  bucket = aws_s3_bucket.demobucket.id
  block_public_acls = false
  block_public_policy = false
}

# Создание ключа шифрования, который будет шифровать объекты ведра
resource "aws_kms_key" "mykey" {
  deletion_window_in_days = "20"
}

# Создание ведра с именем terraformdemobucket
resource "aws_s3_bucket" "demobucket" {
  bucket = terraformdemobucket
  force_destroy = false
  server_side_encryption_configuration {
    rule {
        apply_server_side_encryption_by_default {
        kms_master_key_id = aws_kms_key.mykey.arn
        sse_algorithm = "aws:kms"
      }
    }
  }
  # Хранение нескольких версий объекта в одном ведре
  versioning {
    enabled = true
  }
}

3. Теперь выполните нижеприведенные команды, чтобы перейти в каталог ~\\terraform-s3-demo и инициировать Terraform. Terraform инициализирует плагины и провайдеры, которые необходимы для работы с ресурсами.

Обычно Terraform использует трехкомандный подход по порядку terraform init, terraform plan и terraform apply.

cd ~\terraform-s3-demo       # Перейдите в каталог ~\terraform-s3-demo
terraform init               # Инициируйте Terraform
terraform plan               # Убедитесь, что синтаксис вашей конфигурации верен
terraform apply -auto-approve # Проведите AWS S3 ведро

Создание экземпляров AWS EC2 и IAM-пользователей

В предыдущем разделе вы узнали, как создать один объект (ведро AWS S3) с использованием Terraform с помощью AWS Provider. Но, на самом деле, вы можете создать несколько объектов одного и того же типа с использованием Terraform с помощью AWS Provider.

1. Создайте папку с именем ~/terraform-ec2-iam-demo,, а затем перейдите в нее

2. Откройте ваш любимый редактор кода, скопируйте/вставьте конфигурацию ниже и сохраните файл как main.tf в каталоге ~/terraform-ec2-iam-demo.

Код ниже создает два экземпляра EC2 ec21a и ec21a, с t2.micro и t2.medium типами экземпляров, затем создает IAM пользователей с четырьмя разными именами. Объявленный в коде ami – это Amazon Machine Image (AMI), который предоставляет информацию, необходимую для запуска экземпляра, такую как тип ОС, какое программное обеспечение устанавливать и т. д.

Вы можете найти AMI Linux с помощью консоли Amazon EC2.

# Создание экземпляра с типом экземпляра t2.micro и t2.medium
resource "aws_instance" "my-machine" {
# Объявление AMI 
  ami = "ami-0a91cd140a1fc148a"
  for_each  = {
      key1 = "t2.micro"
	    key2 = "t2.medium"
   }
  instance_type  = each.value
	key_name       = each.key
    tags =  {
	   Name  = each.value
	}
}
# Создание IAM-пользователей с четырьмя разными именами
resource "aws_iam_user" "accounts" {
  for_each = toset( ["Account1", "Account2", "Account3", "Account4"] )
  name     = each.key
}

3. Затем создайте еще один файл, скопируйте/вставьте код ниже и сохраните файл как vars.tf в каталоге ~/terraform-ec2-iam-demo.

Нижеприведенный код объявляет все переменные, на которые ссылаются в файле main.tf. После выполнения кода Terraform переменной tag_ec2 со значениями ec21a и ec21b присваиваются два экземпляра EC2, определенные в файле main.tf.

variable "tag_ec2" {
  type = list(string)
  default = ["ec21a","ec21b"]
}

4. Создайте еще один файл конфигурации Terraform с именем output.tf в каталоге ~/terraform-ec2-iam-demo, затем скопируйте/вставьте код ниже в файл output.tf.

После успешного выполнения команды terraform apply вы должны увидеть значения ${aws_instance.my-machine.*.id} и ${aws_iam_user.accounts.*.name} в конце вывода команды.

Нижеприведенный код указывает Terraform ссылаться на ресурсы aws_instance и aws_iam_user, определенные в файле конфигурации main.tf.

output "aws_instance" {
   value = "${aws_instance.my-machine.*.id}"
}
output "aws_iam_user" {
   value = "${aws_iam_user.accounts.*.name}"
}

5. Создайте еще один файл конфигурации в каталоге ~/terraform-ec2-iam-demo с именем provider.tf и вставьте следующий код в файл provider.tf. Файл provider.tf определяет провайдер AWS для Terraform, чтобы Terraform знал, как взаимодействовать со всеми ресурсами AWS, которые вы определили на предыдущих шагах.

provider "aws" {
   region = "us-east-2"
 }

6. Теперь убедитесь, что все необходимые файлы, перечисленные ниже, находятся в папке ~/terraform-ec2-iam-demo, выполнив команду tree.

Showing all the Terraform configuration files required

7. Выполните указанные ниже команды по порядку, чтобы инициализировать Terraform и создать экземпляры AWS EC2 и пользователей IAM.

terraform init
terraform plan
terraform apply
Terraform apply command executed successfully.

Наконец, перейдите в консоль управления AWS, а затем перейдите в службу AWS EC2 и консоль IAM.

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

Verifying the two EC2 instances that got created using Terraform
Verifying the four IAM users that got created using Terraform

Заключение

С помощью этого исчерпывающего руководства у вас теперь есть необходимые знания для работы с провайдером AWS, от объявления до выполнения AWS Provider в рамках Terraform. Вы также узнали, как AWS Provider позволяет безопасно объявлять учетные данные различными способами.

Теперь какую службу AWS вы собираетесь управлять с помощью AWS Provider и Terraform?

Source:
https://adamtheautomator.com/terraform-aws/