# AWS Provider: настройки и где Terraform берёт ключи _Провайдеры · TerraformLab Knowledge Base_ **TL;DR:** AWS-провайдер ищет credentials в нескольких местах подряд: env-переменные, ~/.aws/credentials, IAM-роль инстанса. Чаще всего достаточно `aws configure` локально или роль на EC2, больше ничего не настраивать. ## Что делает 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/kb/tf-init.md)) из реестра Terraform Registry. ## Минимальная конфигурация ```hcl terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.60" } } } provider "aws" { region = "us-east-1" } ``` Credentials не указаны, провайдер ищет их сам по цепочке (см. Ниже). ## Credentials chain, где провайдер ищет ключи AWS Provider пробует места **по порядку**. Первое подходящее, выигрывает: 1. **Параметры в блоке provider** (`access_key`, `secret_key`). **Так не делать в проде**, credentials в коде. 2. **Переменные окружения**: - `AWS_ACCESS_KEY_ID` - `AWS_SECRET_ACCESS_KEY` - `AWS_SESSION_TOKEN` (для временных credentials) - `AWS_DEFAULT_REGION` или `AWS_REGION` 3. **Shared credentials file** `~/.aws/credentials` (создаётся командой `aws configure`). 4. **EC2 Instance Metadata Service (IMDS)**, если Terraform запущен на EC2-инстансе с IAM-ролью. 5. **ECS / EKS Task Role**, для контейнеризованных сред. **Самый правильный способ для разработчика:** ```bash aws configure # один раз, ввели ключи; провайдер найдёт их сам ``` **Самый правильный способ для прод-сервера:** IAM-роль на EC2 / ECS task role / IRSA в EKS. Ключи нигде не лежат, они выдаются короткоживущими через IMDS. ## Регион, обязательный параметр AWS-сервисы региональны: S3 в `us-east-1` не виден из `eu-central-1`. Регион можно задать тремя способами: ```hcl provider "aws" { region = "us-east-1" } ``` или env var: ```bash export AWS_DEFAULT_REGION=us-east-1 terraform apply ``` или в `~/.aws/config`: ```ini [default] region = us-east-1 ``` Если регион не задан **нигде**, `terraform plan` упадёт с ошибкой «no valid credential sources found». Не самая понятная формулировка, но причина именно в регионе или ключах. ## `default_tags`, теги на всё подряд Один из самых полезных параметров провайдера: ```hcl 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: ```hcl 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" } } ``` Что произойдёт: 1. Провайдер сначала идёт по credentials chain, найдёт ключи в env/файле. 2. С этими ключами вызывает AWS STS `AssumeRole` и получает **временные** credentials, действующие 1 час. 3. Все дальнейшие вызовы AWS API идут с временными credentials. Это намного безопаснее, чем хранить ключи целевого аккаунта. ## Несколько регионов одновременно Через `alias` (см. [tf-provider-block](/terraform/kb/tf-provider-block.md)): ```hcl 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` указывает на один, а env `AWS_ACCESS_KEY_ID` на другой, env побеждает (по credentials chain). Всегда проверяйте `aws sts get-caller-identity` перед опасными операциями. - **default_tags могут конфликтовать с провайдер-уровневыми ограничениями.** Например, EBS-volume не поддерживает все типы тегов; теги типа `aws:created-by` зарезервированы AWS. - **`assume_role` стоит времени.** Каждый вызов STS, это ещё один HTTP-запрос. Не должно быть болью, но на больших applies заметно. ## Команды ```bash aws sts get-caller-identity ``` Проверить, под какими credentials сейчас работает AWS CLI/Terraform. Первое что запустить если 'почему-то не ту инфру вижу'. ```bash aws configure ``` Интерактивная настройка credentials. Создаёт `~/.aws/credentials` и `~/.aws/config`. ```bash aws configure list ``` Показывает, какие credentials и регион сейчас активны, и откуда они взяты (env vs file vs IAM). ```bash AWS_PROFILE=staging terraform plan ``` Запустить plan под конкретным профилем без переключения дефолтного. ## См. также - [Блок provider: кому Terraform будет звонить](/terraform/kb/tf-provider-block.md) - [LocalStack: учебный AWS, который живёт в Docker](/terraform/kb/localstack-provider.md) - [terraform init: первая команда в любом проекте](/terraform/kb/tf-init.md)