Что делает AWS-провайдер
AWS Provider, это плагин-переводчик. Вы пишете в HCL resource "aws_s3_bucket" ..., провайдер превращает это в HTTP-запрос к AWS API PUT /buckets/.... Плагин знает все 300+ типов AWS-ресурсов: S3, EC2, IAM, Lambda, RDS, и так далее.
Плагин скачивается командой terraform init (см. tf-init) из реестра Terraform Registry.
Минимальная конфигурация
terraform { required_providers { aws = {source = "hashicorp/aws"
version = "~> 5.60"
}
}
}
provider "aws" {region = "us-east-1"
}
Credentials не указаны, провайдер ищет их сам по цепочке (см. Ниже).
Credentials chain, где провайдер ищет ключи
AWS Provider пробует места по порядку. Первое подходящее, выигрывает:
- Параметры в блоке provider (
access_key,secret_key). Так не делать в проде, credentials в коде. - Переменные окружения:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN(для временных credentials)AWS_DEFAULT_REGIONилиAWS_REGION
- Shared credentials file
~/.aws/credentials(создаётся командойaws configure). - EC2 Instance Metadata Service (IMDS), если Terraform запущен на EC2-инстансе с IAM-ролью.
- ECS / EKS Task Role, для контейнеризованных сред.
Самый правильный способ для разработчика:
aws configure # один раз, ввели ключи; провайдер найдёт их сам
Самый правильный способ для прод-сервера: IAM-роль на EC2 / ECS task role / IRSA в EKS. Ключи нигде не лежат, они выдаются короткоживущими через IMDS.
Регион, обязательный параметр
AWS-сервисы региональны: S3 в us-east-1 не виден из eu-central-1. Регион можно задать тремя способами:
provider "aws" {region = "us-east-1"
}
или env var:
export AWS_DEFAULT_REGION=us-east-1
terraform apply
или в ~/.aws/config:
[default]
region = us-east-1
Если регион не задан нигде, terraform plan упадёт с ошибкой «no valid credential sources found». Не самая понятная формулировка, но причина именно в регионе или ключах.
default_tags, теги на всё подряд
Один из самых полезных параметров провайдера:
provider "aws" {region = "us-east-1"
default_tags { tags = {Project = "linuxlab-courses"
Environment = "dev"
ManagedBy = "terraform"
Owner = "platform-team"
}
}
}
Теперь каждый ресурс получает эти теги автоматически. Это:
- Решает проблему «кто это создал?» в счетах за облако.
- Упрощает поиск/удаление:
aws ec2 describe-instances --filters Name=tag:Project,Values=linuxlab-courses. - Даёт основу для FinOps-репортов.
Если у ресурса есть собственный tags, они смержатся с default_tags. Точечные теги при коллизии перекрывают глобальные.
assume_role, работа с другими аккаунтами
В крупных компаниях один AWS-аккаунт на команду; cross-account доступ через IAM Role:
provider "aws" {region = "us-east-1"
assume_role {role_arn = "arn:aws:iam::123456789012:role/TerraformDeployerRole"
session_name = "terraform-from-local"
external_id = "secret-shared-with-the-target-account"
}
}
Что произойдёт:
- Провайдер сначала идёт по credentials chain, найдёт ключи в env/файле.
- С этими ключами вызывает AWS STS
AssumeRoleи получает временные credentials, действующие 1 час. - Все дальнейшие вызовы AWS API идут с временными credentials.
Это намного безопаснее, чем хранить ключи целевого аккаунта.
Несколько регионов одновременно
Через alias (см. tf-provider-block):
provider "aws" {region = "us-east-1" # default
}
provider "aws" {alias = "europe"
region = "eu-central-1"
}
resource "aws_s3_bucket" "us" {bucket = "my-us-bucket"
}
resource "aws_s3_bucket" "eu" {provider = aws.europe
bucket = "my-eu-bucket"
}
Подводные камни
-
Не пишите
access_keyиsecret_keyв HCL. Это попадёт в git, потом в публичный репозиторий, потом в скан GitGuardian, потом ваши ключи увидит весь мир. Используйте env vars илиaws configure. -
region, не та же штука что Availability Zone. Регион =us-east-1, AZ =us-east-1a. AZ обычно задаётся на уровне конкретного ресурса. -
Между профилями AWS легко запутаться. Если у вас несколько профилей в
~/.aws/credentials, и переменнаяAWS_PROFILEуказывает на один, а envAWS_ACCESS_KEY_IDна другой, env побеждает (по credentials chain). Всегда проверяйтеaws sts get-caller-identityперед опасными операциями. -
default_tags могут конфликтовать с провайдер-уровневыми ограничениями. Например, EBS-volume не поддерживает все типы тегов; теги типа
aws:created-byзарезервированы AWS. -
assume_roleстоит времени. Каждый вызов STS, это ещё один HTTP-запрос. Не должно быть болью, но на больших applies заметно.