Help us understand the problem. What is going on with this article?

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

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権限は与えてません。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした