LoginSignup
0
1

More than 3 years have passed since last update.

terraformで単一アカウントのECRを複数アカウントでアクセスさせる

Posted at

overview

複数アカウントが前提なAWSで、個人的にはECRは一つのアカウントに集約したほうが管理しやすいです。

その集約したECRに対して、各アカウントに権限を与えるような設定を施します。

コード

tree

$ tree ecr/
ecr/
├── main.tf
└── variables.tf

variables.tf

variable "ecr_repositories" {
  type = list(string)

  default = [
    "hoge", // https://github.com/xxxxx/hoge
    "fuga", // https://github.com/xxxxx/fuga
  ]
}

main.tf

/* ECRは1箇所に集約したほうが管理しやすいので、operationアカウントのみに作成します */
resource "aws_ecr_repository" "this" {
  # countでやると、listの中間削除すると全部作り直しになる
  # ので0.12から入ったfor_eachを入れると、問題なくなる
  # https://github.com/hashicorp/terraform/issues/10850
  for_each = toset(var.ecr_repositories)
  name     = each.value

  image_scanning_configuration {
    scan_on_push = true
  }
}

resource "aws_ecr_repository_policy" "this" {
  for_each   = toset(var.ecr_repositories)
  repository = aws_ecr_repository.this[each.value].name

  # もしアカウントが追加されたら、arn:aws:iamを追加してね
  policy = data.aws_iam_policy_document.this.json
}

/* クロスアカウントにECRの操作権限を与えるポリシー */
data "aws_iam_policy_document" "this" {
  statement {
    effect = "Allow"

    principals {
      type = "AWS"

      identifiers = [
        "arn:aws:iam::${var.AWS_ACCOUNT_自分自身のアカウントID}:root",
        "arn:aws:iam::${var.AWS_ACCOUNT_権限を与えたいアカウントID}:root",
        "arn:aws:iam::${var.AWS_ACCOUNT_権限を与えたいアカウントID}:root",
      ]
    }

    # Delete以外を与える
    actions = [
      "ecr:GetAuthorizationToken",
      "ecr:BatchGetImage",
      "ecr:BatchCheckLayerAvailability",
      "ecr:GetDownloadUrlForLayer",
      "ecr:InitiateLayerUpload",
      "ecr:CompleteLayerUpload",
      "ecr:UploadLayerPart",
      "ecr:DescribeImages",
      "ecr:PutImage",
      "ecr:DescribeRepositories",
      "ecr:GetRepositoryPolicy",
      "ecr:ListImages",
      "ecr:BatchDeleteImage",
    ]
  }
}

# untagged な イメージについては 1日で削除する
resource "aws_ecr_lifecycle_policy" "this" {
  for_each   = toset(var.ecr_repositories)
  repository = aws_ecr_repository.this[each.value].name

  policy = <<EOF
{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Expire images older than 1 days",
      "selection": {
          "tagStatus": "untagged",
          "countType": "sinceImagePushed",
          "countUnit": "days",
          "countNumber": 1
      },
      "action": {
          "type": "expire"
      }
    }
  ]
}
EOF
}

ポイント

for_each = toset(var.ecr_repositories)

コメントにも書いてますが、countでやると、listの中間削除すると全部作り直しになる
のでterraform v0.12 から入ったfor_eachを入れると、問題なくなります。
ref: https://github.com/hashicorp/terraform/issues/10850

untaggedなイメージは削除して良いとして、それ以外のライフサイクルはruleで定義するのは難しそうだったので、Goなどでlifecycleツールを作ってcronで毎日動かす想定をしてます。

なのでまた、アカウントに対してdelete権限は与えてません。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1