レポートの読み取りユーザーに限定的なアクセスを付与する

AWSBeginner
オンラインで実践に進む

はじめに

レポートの利用者に必要なのは、1 つの非公開レポートへのアクセスであり、運用担当者が持つストレージ全体へのアクセスではありません。独立した IAM ID に範囲を限定したアクセスを付与し、実際のリクエストをテストしてから、レポートデータを保持したまま許可を取り消します。

リソース参照と S3 オブジェクトの読み取りの知識を基に進めます。IAM の Action と Resource を理解していることを前提としますが、ロールの信頼関係、インスタンスプロファイル、個人のアクセスキーは不要です。この新しい環境には、両方の CLI ID が準備されています。

認定試験との関連

認定資格 試験のタスク 演習内容
Cloud Practitioner (CLF-C02) Task 2.3 および 3.1 再現可能なインフラストラクチャ設定を通じて、最小権限の ID ベースのポリシーを管理します。
Developer – Associate (DVA-C02) Task 3.3, Skill 3.3.4 インフラストラクチャ定義をデプロイする基礎演習です。
DevOps Engineer – Professional (DOP-C02) Task 2.1 IaC 定義を通じてリソースを管理する基礎演習です。
Solutions Architect – Associate (SAA-C03) Task 1.1 IAM の読み取り用ポリシーの範囲を限定し、許可されるアクセスと拒否されるアクセスを評価する基礎演習です。

この実験で実際に扱うリソースと、保持する対象の境界を示す概念図。

レポートを準備して読み取りユーザーを確認する

このステップでは、レポートストアを作成し、有効な独立した読み取りユーザーが、最初はアクセスできないことを観察します。

デフォルトの CLI ID はインフラストラクチャを管理します。用意された reader プロファイルは、独立した IAM ユーザー report-reader に属します。そのアクセス権を運用担当者から借りているわけではありません。ストレージを作成しても、そのユーザーが自動的に許可されることはありません。プロファイルの選択で変わるのは、AWS リクエストに署名する ID であり、リソース自体ではありません。

準備済みのルートにレポートストアを作成します。

cd /home/labex/project/reader-access
cat > main.tf <<'EOF'
resource "aws_s3_bucket" "reports" {
  bucket = "terraform-reader-reports"
}
resource "aws_s3_object" "report" {
  bucket       = aws_s3_bucket.reports.id
  key          = "reports/current.csv"
  content      = "orders,12\n"
  content_type = "text/csv"
}
EOF
terraform init
terraform plan

追加は 2 つのはずです。適用し、yes を入力します。

terraform apply

独立した読み取りユーザーで、レポートの読み取りを試します。|| true は、意図した失敗の後もこのコマンドブロックを続行できるようにするもので、リクエストを読み取り成功に変えるものではありません。

aws s3api \
  get-object \
  --profile reader \
  --bucket terraform-reader-reports \
  --key reports/current.csv \
  reader-report.csv || true

AccessDenied と表示されるはずです。ID は有効ですが、一致する許可がありません。別の team-reference-reports/keep.txt オブジェクトは、実験を通じて非公開のままにしてください。AWS View は運用担当者の ID でストレージを確認します。その画面でオブジェクトをプレビューできても、読み取りユーザーがアクセスできる証拠にはなりません。 デプロイ後の AWS View:作成したストレージが、保持された参照用レポートの隣に表示されています。

意図したレポートの読み取りだけを許可する

このステップでは、リソース参照を使って IAM の ID ベースのポリシーを構築し、許可される読み取りと禁止される読み取りの両方を検証します。

インラインの ID ベースのポリシーは、1 人のユーザーに直接関連付けられ、そのユーザーにアクションを許可します。s3:GetObject が適用されるのは、バケット ARN ではなくオブジェクト ARN です。jsonencode は Terraform の値を有効な JSON に変換するため、エスケープした JSON 文字列を手動で組み立てずに、通常の HCL リソース参照を使用できます。

policy.tf を作成します。読み取りユーザーの名前は準備済みのものです。ポリシーの対象 ARN は、作成したバケットの ARN と、実際のオブジェクトのキーを組み合わせます。

cat > policy.tf <<'EOF'
resource "aws_iam_user_policy" "reader" {
  name = "ReadReport"
  user = "report-reader"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect   = "Allow"
      Action   = "s3:GetObject"
      Resource = "${aws_s3_bucket.reports.arn}/${aws_s3_object.report.key}"
    }]
  })
}
EOF
terraform plan

プランはバケットとレポートを保持しながら、ポリシーを 1 つ追加します。適用し、yes を入力します。

terraform apply

同じ reader プロファイルで対象を読み取ります。

aws s3api \
  get-object \
  --profile reader \
  --bucket terraform-reader-reports \
  --key reports/current.csv \
  reader-report.csv
cat reader-report.csv

orders,12 と表示されるはずです。次に、同じ ID で無関係の非公開オブジェクトを読み取ります。

aws s3api \
  get-object \
  --profile reader \
  --bucket team-reference-reports \
  --key keep.txt \
  unrelated-report.txt || true

参照用データがダウンロードされるのではなく、AccessDenied と表示されるはずです。このポリシーはレポートの読み取りだけを許可し、レポートの書き込みや削除を許可してはいけません。対象の読み取りが成功していても、アクションやリソースに広範なワイルドカードを使うと、意図しないアクセスを生む場合があります。チェックはサービス側のポリシーの意味を読み取り、実際に許可される読み取りと禁止される読み取りを実行します。特定の JSON レイアウトを要求するものではありません。同等の文字列/リスト形式の式や、レポートだけを対象とするプレフィックスでも、新しいアクションを許可せずにこの課題を満たせます。

データを削除せずに許可を取り消す

このステップでは、Terraform を通じてポリシーを削除し、アクセスが変わってもレポートが残ることを確かめます。

リソースブロックを削除すると、その管理対象リソースの削除が提案されます。ストレージ設定は変更せず、policy.tf だけを削除します。

rm policy.tf
terraform plan -out=revoke.tfplan
terraform show revoke.tfplan

ポリシーの削除が 1 つ提案され、バケットやオブジェクトの削除はないはずです。保存済みの成果物を適用します。

terraform apply revoke.tfplan

同じ読み取りユーザーで、対象の読み取りを再試行します。

aws s3api \
  get-object \
  --profile reader \
  --bucket terraform-reader-reports \
  --key reports/current.csv \
  after-revoke.csv || true

AccessDenied と表示されるはずです。許可を取り消しても、すでにダウンロードしたローカルファイルは削除されません。また、reader-report.csv が存在しても、新しいリクエストが許可される証拠にはなりません。デフォルトの運用担当者 ID で、保存済みのレポートを照会します。

aws s3api \
  get-object \
  --bucket terraform-reader-reports \
  --key reports/current.csv \
  retained-report.csv
cat retained-report.csv

レポートには引き続き orders,12 が含まれます。データを変更せずに、認可の境界を変更しました。Action と Resource の違いについては、IAM ポリシーの要素を参照してください。

自分が所有するレポートストアを削除する

このステップでは、アクセスと許可取り消しのチェックを完了した後で、ストレージを削除します。

このルートの残りのリソースを削除し、yes を入力します。

terraform destroy

バケットとレポートオブジェクトは削除されます。用意された読み取りユーザーとチームの参照用レポートは準備済みの環境に属し、このルートの状態には含まれません。最後の対応付けと、保持された参照用レポートを確認します。

terraform state list
aws s3api \
  list-buckets \
  --query 'Buckets[].Name'
aws s3api \
  head-object \
  --bucket team-reference-reports \
  --key keep.txt \
  --query ContentLength

状態の一覧は空になり、参照用レポートは残ります。最後のチェックが終わるまで、準備済みの両方の CLI ID の設定を保持してください。

まとめ

jsonencode とリソース参照で IAM の ID ベースのポリシーを定義し、独立した読み取りユーザーで許可されるリクエストと禁止されるリクエストをテストして、レポートデータを削除せずに許可を取り消し、自分が所有するストアだけを削除しました。