🪣

terraformで特定のIAMユーザしかアクセスできないs3バケットを作る

2023/05/24に公開

user1はs3バケットのファイル操作出来るが、それ以外は不可
という環境をterraformで作りました。
IAM、バケットポリシーの良い素振りになると思います。

コードはこちら

main.tf
main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.65.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
  default_tags {
    tags = {
      env       = "dev"
      provision = "terraform"
    }
  }
}

## IAMユーザ
data "aws_iam_policy" "S3FullAccess" {
  arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
}

resource "aws_iam_user" "user1" {
  name          = "user1"
  force_destroy = true
}

resource "aws_iam_access_key" "key1" {
  user = aws_iam_user.user1.name
}

resource "aws_iam_user" "user2" {
  name          = "user2"
  force_destroy = true
}

resource "aws_iam_access_key" "key2" {
  user = aws_iam_user.user2.name
}

resource "aws_iam_user_policy_attachment" "attach1" {
  user       = aws_iam_user.user1.name
  policy_arn = data.aws_iam_policy.S3FullAccess.arn
}

resource "aws_iam_user_policy_attachment" "attach2" {
  user       = aws_iam_user.user2.name
  policy_arn = data.aws_iam_policy.S3FullAccess.arn
}

## S3
resource "aws_s3_bucket" "testbucket" {
  bucket = "testbucket-20230524"
}

resource "aws_s3_bucket_policy" "testbucketpolicy" {
  bucket = aws_s3_bucket.testbucket.id

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowUserAccess",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "${aws_s3_bucket.testbucket.arn}/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:username": "${aws_iam_user.user1.name}"
        }
      }
    }
  ]
}
EOF
}

事前準備

  • main.tfの実行
  • s3にアクセス可能なIAMユーザ2つが作成されるため、それぞれアクセスキーとシークレットアクセスキーを控えます。

s3に適当なファイルをプッシュする

やってみましょう。

user2

失敗

$ aws s3 cp ./test.txt s3://testbucket-20230524/test.txt --profile user2
upload failed: ./test.txt to s3://testbucket-20230524/test.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

user1

成功

$ aws s3 cp ./test.txt s3://testbucket-20230524/test.txt --profile user1
upload: ./test.txt to s3://testbucket-20230524/test.txt

OKです

ファイルを削除する

削除もしてみます。

user2

失敗

$ aws s3 rm s3://testbucket-20230524/test.txt --profile user2
delete failed: s3://testbucket-20230524/test.txt An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied

user1

成功

$ aws s3 rm s3://testbucket-20230524/test.txt --profile user1
delete: s3://testbucket-20230524/test.txt

なぜ?

  • StringNotEqualsで、user1ではないユーザを表現している
    • user1ではないユーザをすべてdenyするということ
  • 言い換えるとuser1のみallowする

ということです

      "Effect": "Deny",
      "Principal": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:username": "${aws_iam_user.user1.name}"

ややこしいですね

後片付け

$ terraform destroy

参考

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html
https://qiita.com/sonots/items/bef1ba496d00d9cb7885

Discussion