ローカル開発環境における Terraform の Google Cloud 認証方法の推奨と仕組み #cm_google_cloud_adcal_2024

ローカル開発環境における Terraform の Google Cloud 認証方法の推奨と仕組み #cm_google_cloud_adcal_2024

Terraform をローカル開発環境で利用する際の Google Cloud の認証方法について纏めました。非常に簡単に認証できる推奨の方法や認証のアーキテクチャについて解説します。
Clock Icon2024.12.16

はじめに

クラスメソッドの Google Cloud Advent Calendar 2024 の 16 日目のブログです!
Google Cloud Advent Calendar 2024 では Google Cloud が大好きな弊社エンジニアが技術ブログを持ち回りで毎日執筆中ですので、ご覧になっていただけると嬉しいです。

https://qiita.com/advent-calendar/2024/cm-google-cloud

本日は ローカル開発環境における Terraform による Google Cloud の認証方法について解説します。

Google Cloud 推奨の Terraform 認証方法

Terraform で Google Cloud リソースをデプロイする際、もちろんではありますが Google Cloud の認証が必要となります。
Google Cloud が推奨する Terraform の認証方法は アプリケーションのデフォルト認証情報(Application Default Credentials, ADC) を利用した方式です。

ADC とは

Terraform の認証について話をする前に、まずは ADC について説明します。

Google Cloud では、アプリケーションから 様々な Google Cloud APIにアクセスするためにクライアントライブラリが用意されています。クライアントライブラリを利用して Google Cloud API にアクセスすると、ライブラリが自動で認証処理を実行してくれます。この認証処理の方法のことを ADC と言います。これにより、ユーザはアプリケーションに認証の仕組みを個別実装する必要がなくなります。

ADC の仕組み

ADC の仕組みを簡単に解説します。ADC による認証は大きく以下の流れで行われます。

  1. 認証情報の用意 (ユーザによる設定)
  2. アクセストークンの取得 (クライアントライブラリによる自動取得)

ADC はユーザが設定した認証情報を自動で検索し、認証情報を Google Cloud に渡して有効期限の短いアクセストークン(デフォルト1時間)を取得し、このアクセストークンを使って Google Cloud の認証を受けることとなります。

概要
ADC による認証の概要

ADC のための認証情報の準備

なお、ADC は以下の優先順位で認証情報をアプリケーション環境から自動検索します。

  1. GOOGLE_APPLICATION_CREDENTIALS 環境変数に設定された認証情報
  2. Google Cloud CLI で取得されたユーザ認証情報
  3. メタデータサーバの認証情報

上記のそれぞれの詳細情報はこちらのドキュメントをご参照いただければと思いますが、本ブログの本題であるローカル開発環境から Terraform を認証するケースでは 「2. Google Cloud CLI で設定されたユーザ認証情報」 を使うことを推奨していますので、こちらの方法について少し補足します。

「2. Google Cloud CLI で設定されたユーザ認証情報」を使う場合、Google Cloud CLI の gcloud init コマンドを使用してユーザ認証や接続先 Google Cloud プロジェクトの設定を行い、そのあと gcloud auth application-default login コマンドで認証情報(ローカル ADC ファイル)の生成を行います。ADC では、ここで生成された認証情報を検索して利用し Google Cloud からアクセストークンを受領、受領したアクセストークンで Google Cloud にアクセスするという流れとなります。

Terraform の ADC サポート

Terraform の Google Cloud プロバイダは ADC をサポートしています。そのため、ADC による認証で容易に Google Cloud へのアクセスが実現できます。

Google Cloud プロバイダの認証に関する仕様については以下をご参照ください。
https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#authentication

ユーザ権限を使うべきか、サービスアカウントの権限借用を使うべきか

「Google Cloud CLI で設定されたユーザー認証情報」では、IAM ユーザアカウントを利用した認証か、サービスアカウントの権限借用による認証が利用できます。
IAM ユーザアカウントを利用した認証であれば、ユーザに設定された権限で Terraform が Google Cloud のサービスにアクセスできます。サービスアカウントの権限借用による認証の場合、ユーザが借用したサービスアカウントの権限で Terraform が Google Cloud のサービスにアクセスできます。

結論を申し上げると、Terraform の認証をする場合は IAM ユーザアカウントを利用した認証が良いでしょう。Google Cloud 公式ブログに以下記述があります。

アプリケーションがそれ自体のために動作しているのか、それともエンドユーザーのために動作しているのかを自問してみましょう。

ユーザーが自身のドキュメントにアクセスできるようにするアプリケーションは、エンドユーザーのために動作しています。アプリケーションのためではありません。

日常業務で、gcloud、gsutil、terraform などのツールを使用する場合があります。これらのツールを実行するのはユーザーであるため、ツールもユーザーの認証情報を使うべきです。

ユーザのためのアプリケーションはユーザの認証情報を使うことによって、ユーザが本来操作可能な認可範囲を超えず、監査ログによるアクセス記録の追跡を容易にできるということですね。

なお、サービスアカウントの権限借用については以下ブログで詳しく説明していますのでご参照ください。
https://dev.classmethod.jp/articles/gcp-gcloud-command-service-account/

やってみた

実際に、ローカル開発環境から Terraform で Google Cloud リソースをデプロイするための認証の動作を見ていきたいと思います。
なお、検証用のローカル開発環境はUbuntu 22.04.2 LTSを利用していますが、その他 Linux ディストリビューションや Windows / Mac 環境でも Google Cloud CLI のインストール以外は同様の手順となります。

また、Terraform を実行するユーザには Compute インスタンス管理者(v1) roles/compute.instanceAdmin.v1 権限を付与しました。

作業手順は以下を参考にしています。
https://cloud.google.com/docs/terraform/authentication?hl=ja

Google Cloud CLI をインストールする

以下を参照し、ローカル開発環境に Google Cloud CLI をインストールします。個々の環境に合わせたインストール方法をご参照ください。

https://cloud.google.com/sdk/docs/install?hl=ja#deb

gcloud init による設定の初期化

gcloud init コマンドで設定を初期化します。

gcloud init

ブラウザによるユーザ認証の URL が表示されたらクリックしログインします。ログイン後、対象プロジェクトの選択を行います。Region や Zone の設定はスキップしていただいて構いません。

ADC のための認証情報の取得

ADC のための認証情報であるローカル ADC ファイルを取得します。以下のコマンドを実行します。

gcloud auth application-default login

出力された URL をクリックすると以下の画面が確認できます。Google Auth Library に対する認証が必要となるためログインします。

ログイン - Google アカウント

ログイン - Google アカウント2

ログイン - Google アカウント3

認証が完了するとコマンドラインに以下が表示されます。

Credentials saved to file: [/home/kaz/.config/gcloud/application_default_credentials.json]

These credentials will be used by any library that requests Application Default Credentials (ADC).
WARNING: 
Cannot add the project "プロジェクト名" to ADC as the quota project because the account in ADC does not have the "serviceusage.services.use" permission on this project. You might receive a "quota_exceeded" or "API not enabled" error. Run $ gcloud auth application-default set-quota-project to add a quota project.

ログに記載されたapplication_default_credentials.jsonがローカル ADC ファイルです。以下のような内容が確認できます。

cat /home/kaz/.config/gcloud/application_default_credentials.json
{
  "account": "",
  "client_id": "xxxxx",
  "client_secret": "xxxxx",
  "refresh_token": "xxxxx",
  "type": "authorized_user",
  "universe_domain": "googleapis.com"
}

Terraform を実行してみる

前述の解説の通り、Terraform の Google Cloud プロバイダには ADC の仕組みが組み込まれています。ADC は自動でローカル ADC ファイルを検索します。そのため、あとは Terraform を実行するだけで自動で認証して Google Cloud サービスにアクセスすることができます。

以下の Terraform 設定ファイルを用意します。

main.tf
provider "google" {
  region = "asia-northeast1"
  project = var.project_id
}

variable "project_id" {
  type    = string
}

resource "google_compute_instance" "web-server" {
  name         = "tf-instance"
  machine_type = "e2-micro"
  zone         = "asia-northeast1-a"

  boot_disk {
    initialize_params {
      image = "projects/debian-cloud/global/images/debian-12-bookworm-v20241112"
      size  = 20
      type  = "pd-balanced"
    }
  }

  network_interface {
    network = "default"
  }

}

Terraform を実行します。

$ terraform init
$ terraform apply
var.project_id
  Enter a value: プロジェクトIDを入力

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:    
  + create

Terraform will perform the following actions:

  # google_compute_instance.web-server will be created
  + resource "google_compute_instance" "web-server" {

~~~

上記のように、Terraform が問題無く実行でき、Google Cloud にリソースが作成できることがわかります。

権限を確認してみる

現在、認証したユーザには Compute インスタンス管理者(v1) roles/compute.instanceAdmin.v1 権限を付与しています。ユーザに付与された権限で Terraform を実行できているか確認してみます。
ここでは Cloud Storage バケットの作成を試み、バケット作成が権限範囲外により拒否されるか確認してみたいと思います。main.tfに以下を追加します。

main.tf

~~~

resource "google_storage_bucket" "demo_bucket" {
  name          = "${var.project_id}-demo_bucket"
  location      = "asia-northeast1"
}

Terraform を実行します。

$ terraform apply
var.project_id
  Enter a value: プロジェクトIDを入力

~~~

╷
│ Error: googleapi: Error 403: <USER_ID> does not have storage.buckets.create access to the Google Cloud project. Permission 'storage.buckets.create' denied on resource (or it may not exist)., forbidden
│
│   with google_storage_bucket.demo_bucket,
│   on main.tf line 29, in resource "google_storage_bucket" "demo_bucket":29: resource "google_storage_bucket" "demo_bucket" {
│
╵

権限が不足していることにより Cloud Storage バケットが作成できない旨のエラーが表示されました。認証したユーザに付与した権限で Terraform が実行できていることがわかりました。

まとめ

  • ローカル開発環境における Google Cloud 認証の推奨方法は ADC を利用した方法。
  • ADC を利用するための準備は Google Cloud CLI を利用した gcloud initgcloud auth application-default login だけ。
  • サービスアカウントの権限借用ではなく、ユーザ権限を利用した認証とした方が良い。

おわりに

Terraform と Google Cloud の親和性は高く、リソースを管理するのに Terraform は非常に有用です。認証の仕組みも簡単に準備できることがわかったと思いますので、Terraform を利用したことがないユーザも気軽に Google Cloud x Terraform を始めてみてはいかがでしょうか。
なお、Cloud Shell には Terraform がプリインストールされています。Cloud Shell で利用する場合は ADC による認証は不要ですので、さらに簡単に Google Cloud での Terraform を始められます。

Google Cloud Advent Calendar 2024 の 明日 12/17 投稿は kobayashi.m です!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.