Предоставление приложению доступа к его отчётам

AWSBeginner
Практиковаться сейчас

Введение

Работающему приложению нужно читать закрытый отчёт. Вы свяжете роль IAM и профиль экземпляра через ссылки Terraform, предоставите доступ к нужному объекту и проверите фактические запросы приложения до и после удаления разрешения.

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

Связь с сертификацией

Сертификация Задача экзамена Практика
Cloud Practitioner (CLF-C02) Задача 2.3 Роли IAM и разрешения на объекты с минимальными привилегиями.
Solutions Architect – Associate (SAA-C03) Задача 1.1 Доступ рабочей нагрузки на основе роли с ограниченными разрешениями.
CloudOps Engineer – Associate (SOA-C03) Задача 4.1 Базовая реализация роли и политики IAM.

Обзор лабораторной работы

Обзор концепции: приложение EC2 использует профиль экземпляра и роль IAM для чтения report.csv, тогда как доступ к private.csv остаётся запрещённым.

Предоставление работающему приложению идентичности роли

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

Верхний AWS View отображает те же ресурсы, которые запрашиваются в Terminal. Его селектор Request path позволяет запросить состояние приложения, идентичность рабочей нагрузки или любой из двух закрытых объектов. Terminal использует подготовленную идентичность оператора; приложение использует собственную роль экземпляра. Успешный запрос оператора не доказывает, что у приложения есть разрешение.

Изучите подготовленную корневую конфигурацию и запишите идентификатор экземпляра:

cd /home/labex/project/application-reports
cat terraform.tfvars.json
cat application.tf
terraform state list
INSTANCE_ID=$(terraform output -raw instance_id)
echo "$INSTANCE_ID"
REPORT_BUCKET=$(terraform output -raw report_bucket)
echo "$REPORT_BUCKET"

Существующее состояние управляет экземпляром приложения. Сеть, AMI, бакет и эталонное приложение предоставлены отдельно. User Data уже указывает приложению на report.csv в подготовленном бакете, но не содержит ключа доступа.

В AWS View выберите application-server, User · 198.51.100.10, Application · 8081 и Health, затем нажмите Send request. Ожидайте Connected · 200 и Report application. Выберите Private report и отправьте запрос снова. Приложение пока не может его прочитать и сообщает Connected · 503 с Application storage unavailable: HTTP-приложение доступно, но у него нет учётных данных рабочей нагрузки.

Политика доверия роли IAM определяет, кто может принять эту роль. Профиль экземпляра связывает роль с EC2. Ни один из этих объектов сам по себе не предоставляет разрешение читать объект S3. Создайте эти два ресурса:

cat > identity.tf <<'HCL'
resource "aws_iam_role" "reports" {
  name = "tf-report-reader"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = { Service = "ec2.amazonaws.com" }
      Action = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_instance_profile" "reports" {
  name = "tf-report-reader"
  role = aws_iam_role.reports.name
}
HCL
sed -i '/vpc_security_group_ids/a\  iam_instance_profile = aws_iam_instance_profile.reports.name' application.tf
terraform fmt
terraform validate
terraform plan

Команда sed вставляет атрибут профиля экземпляра после существующего атрибута группы безопасности. Его ссылка на ресурс связывает работающий экземпляр с профилем, который ссылается на роль. Изучите план: создание роли и профиля и обновление существующей связи экземпляра без замены экземпляра или изменения User Data.

Примените изменения и введите yes:

terraform apply

Изучите фактическую связь и профиль:

aws ec2 \
  describe-iam-instance-profile-associations \
  --filters "Name=instance-id,Values=$INSTANCE_ID" \
  --query 'IamInstanceProfileAssociations[].{Instance:InstanceId,State:State,Profile:IamInstanceProfile.Arn}'
aws iam \
  get-instance-profile \
  --instance-profile-name tf-report-reader \
  --query 'InstanceProfile.{Name:InstanceProfileName,Roles:Roles[].RoleName}'

В AWS View выберите Workload identity для application-server и отправьте запрос. Ожидайте Connected · 200 и ARN, содержащий assumed-role/tf-report-reader/. Он поступает от STS внутри гостевой системы с использованием временных учётных данных роли, а не от оператора Terminal.

Выберите Private report и отправьте запрос снова. Ожидайте Connected · 403 и Access denied. Идентичность роли теперь работает, но разрешения на чтение объекта пока нет. Это намеренная ошибка авторизации.

Предоставление доступа только к нужному отчёту

На этом шаге вы предоставите роли приложения одно разрешение на чтение объекта и проверите как разрешённый отчёт, так и посторонний закрытый объект.

Политика разрешений роли определяет, что может делать её сеанс. Используйте политику идентичности, разрешающую s3:GetObject для точного ARN report.csv. Имя бакета берётся из предоставленного входного значения; роль — из ссылки на ресурс. Статическим учётным данным не место в User Data.

cat > permissions.tf <<'HCL'
resource "aws_iam_role_policy" "report" {
  name = "ReadApplicationReport"
  role = aws_iam_role.reports.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Action = ["s3:GetObject"]
      Resource = ["arn:aws:s3:::${var.report_bucket}/report.csv"]
    }]
  })
}
HCL
terraform fmt
terraform validate
terraform plan

План добавляет одну политику. Он не должен заменять приложение или создавать новый бакет. Примените изменения и введите yes:

terraform apply

В AWS View оставьте выбранными application-server, User и порт 8081. Выберите Private report и отправьте запрос. Ожидайте Connected · 200 с отчётом:

period,total
Q1,320

Выберите Unrelated private object и отправьте ещё один запрос. Ожидайте Connected · 403 и Access denied. Приложение может читать свой отчёт, тогда как private.csv остаётся вне разрешения. Этот 403 — фактический результат авторизации S3, возвращённый доступным приложением, а не ошибка сетевого подключения.

Вернитесь к Workload identity и отправьте запрос снова. Его ARN по-прежнему должен определять роль рабочей нагрузки. Подтвердите согласованность:

terraform plan

Ожидайте No changes. Пример результата: приложение читает закрытый отчёт с идентичностью своей роли. Идентификаторы ресурсов различаются в каждой среде.

Отзыв разрешения и проверка фактического результата

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

Удаление разрешения отличается от отсоединения профиля или остановки экземпляра. Сохраните роль и профиль, удалите конфигурацию ресурса политики, затем изучите удаление:

rm permissions.tf
terraform plan

Ожидайте удаление политики чтения без замены экземпляра. Примените изменения и введите yes:

terraform apply

Независимо прочитайте имена оставшихся встроенных политик:

aws iam \
  list-role-policies \
  --role-name tf-report-reader \
  --query PolicyNames

Ожидайте []. В AWS View отправьте приложению запрос Workload identity. Он по-прежнему возвращает Connected · 200 с тем же именем роли. Затем отправьте запросы Private report и Unrelated private object. Оба должны вернуть Connected · 403 и Access denied. Отказ в чтении доказывает, что удаление разрешения влияет на фактические запросы рабочей нагрузки, хотя приложение и его связь с ролью всё ещё существуют.

terraform plan

Ожидайте No changes.

Удаление управляемых ресурсов с сохранением предоставленных данных

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

Политика уже удалена. Изучите оставшуюся область удаления:

terraform plan -destroy

Ожидайте три управляемых ресурса: экземпляр приложения, профиль экземпляра и роль IAM. Затем удалите их и введите yes:

terraform destroy

Завершение работы того же экземпляра должно подтверждаться самим сервисом:

aws ec2 \
  describe-instances \
  --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[].Instances[].{ID:InstanceId,State:State.Name}'
terraform state list

Ожидайте terminated и отсутствие управляемых ресурсов в состоянии. Запросите списки ролей и профилей по точным именам; успешно полученные пустые списки подтверждают отсутствие, не принимая ошибку аутентификации за очистку:

aws iam list-roles --query "Roles[?RoleName=='tf-report-reader'].RoleName"
aws iam list-instance-profiles --query "InstanceProfiles[?InstanceProfileName=='tf-report-reader'].InstanceProfileName"

Оба возвращают []. Бакет предоставлен вне этого состояния. Используйте оператора Terminal, чтобы прочитать оба сохранённых объекта и изучить их байты. Эти чтения оператором проверяют сохранность; ограниченный доступ приложения проверялся отдельно через его роль.

aws s3api get-object --bucket "$REPORT_BUCKET" --key report.csv /tmp/retained-report.csv
cat /tmp/retained-report.csv
aws s3api get-object --bucket "$REPORT_BUCKET" --key private.csv /tmp/retained-private.csv
cat /tmp/retained-private.csv

Отчёт остаётся period,total / Q1,320; посторонний объект остаётся private,retained. В AWS View выберите reference-server, User, Application · 8081 и Health, затем отправьте запрос. Ожидайте Connected · 200 и Reference application.

Сохраните файлы Terraform для изучения. Последующий обычный план предложил бы повторное создание по оставшейся конфигурации; успешное удаление не требует удаления этой конфигурации.

Резюме

Вы связали экземпляр приложения с ролью через ссылки Terraform, разобрались в различии между идентичностью роли и разрешением на объект и проверили как успешное чтение закрытого отчёта, так и отказ для постороннего объекта. Затем вы отозвали разрешение, увидели фактическую ошибку авторизации и удалили управляемые ресурсы, сохранив предоставленные данные и эталонное приложение.