🐥

Terraform活用法!コードとPRで管理する社内のGCP権限管理!

2023/10/03に公開

1. 背景

インフラエンジニア以外の人がインフラリソースの権限を得る場合、基本的にインフラエンジニアにお願いする形になってるところが多いかと思います。
ただし、一時的な権限をお願いしたい場合、出来れば自立的に行い確認フローだけお願いする形にしたいですよね。
今回は、terraformで管理されたインフラにおいて自立的に権限を申請しやすい構成を紹介します。

また、前提としてクラウドプロバイダはGCPで行います。

2. ディレクトリ構成

ディレクトリ構成は以下になります。

├── _access_requests
│   ├── temp_roles.tf
│   └── variables.tf
├── locals_teams.tf
└── main.tf

main.tfで基本となる権限を管理し、実際の開発メンバーの権限管理はlocals_teams.tfで行います。
一時権限は_access_requestsディレクトリ内で分かりやすく管理することで、効率的な権限申請と承認プロセスを実現します。

3. 大枠の権限を管理するファイル

main.tfでは、google_project_iam_bindingを使い、大枠の権限(editor,viewer,owner)を適応しています。また、members引数を使い複数のユーザーに対応できるようにしています。
google_project_iam_bindingを使うことで、手動設定されたとしても権限がなくなるので、必然的にコード管理運用が必要になるようにしています。
メンバー自体は、locals_teams.tfにて、writer、readerに振り分ける形です。

main.tf

locals {
  project_id = "your-gcp-project-id"
}

resource "google_service_account" "my_service_account" {
  account_id   = "my-service-account-a"
  display_name = "My Service Account"
  project      = local.project_id
}

resource "google_service_account" "my_service_account_b" {
  account_id   = "my-service-account-b"
  display_name = "My Service Account"
  project      = local.project_id
}

resource "google_project_iam_binding" "writer" {
  project = local.project_id
  role    = "roles/editor"

  members = local.writer
}

resource "google_project_iam_binding" "reader" {
  project = local.project_id
  role    = "roles/viewer"

  members = local.reader
}

※環境ごとに設けたい場合は、別々で作成します。

locals_teams.tf

locals {
  /* -------------------------------------------------------------
      - writer: 実装関係者
      - reader: 運用保守・設計等閲覧が必要な人
     ------------------------------------------------------------- */

  writer = toset([
    "serviceAccount:my-service-account-a@your-gcp-project-id.iam.gserviceaccount.com"
  ])

  reader = toset([
    "serviceAccount:my-service-account-b@your-gcp-project-id.iam.gserviceaccount.com"
  ])
}

3. 一時権限を申請するファイル

一時権限をリソース管理するtemp_roles.tfでは、google_project_iam_memberを使い一時的な権限リソースを追加して、PRとして申請しています。
この時に大事なのは、expressionで必要な期間のみに制限していることです。

また、インフラサイドでは他のエンジニアが申請しやすいようにsampleコードのコメントアウトを残すといいです。

resource "google_project_iam_member" "my_service_account_a_container_admin" {

  project = "your-gcp-project-id"
  role    = "roles/container.admin"
  member  = "serviceAccount:my-service-account-a@your-gcp-project-id.iam.gserviceaccount.com"

  condition {
    title       = "my_service_account_a_container_admin"
    expression  = "request.time < timestamp(\"2023-12-31T00:00:00Z\")"
  }
}

4. 注意点

権限の申請と承認プロセスにおいて、申請者が必要以上の権限をリクエストするリスクがあります。
これを防ぐため、権限の範囲と使用目的を明確にし、レビュアーはそれを厳密に確認する必要があります。

5. まとめ

この記事では、Terraformを用いてインフラエンジニア以外も効率よくGCPの権限を申請・管理する方法を紹介しました。AWSなど他のクラウドプロバイダでも応用可能です。
チームのメンバーの変動に柔軟に対応できるので、プロジェクトの効率的な管理を行うことができます。

Discussion