GCP 環境をプロビジョニングするための Terraform の基本的な設定を記載します。
本ページで利用する terraform のバージョンは以下のとおりです。
[vagrant@localhost myrepo]$ terraform --version
Terraform v0.14.8
簡単な例 (VPC の作成)
以下のような main.tf ファイルを作成します。GCP のサービスアカウントの key ファイルのパスを指定します。サービスアカウントには必要なロールを割り当てておく必要があります。
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "3.60.0"
}
}
}
provider "google" {
credentials = file("./my-service-account-key.json")
project = "my-project-id"
}
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
}
Terraform では対象とする環境に応じて provider を指定します。GCP の場合は hashicorp/google という provider を利用します。
以下のコマンドで provider のバイナリのダウンロード等の初期化処理を行います。
terraform init
変更される内容を dry-run で確認します。
terraform plan
変更を適用します。
terraform apply
terraform が認識している状態を確認します。
terraform show
出力例
# google_compute_network.vpc_network:
resource "google_compute_network" "vpc_network" {
auto_create_subnetworks = true
delete_default_routes_on_create = false
id = "projects/my-project-id/global/networks/terraform-network"
mtu = 0
name = "terraform-network"
project = "my-project-id"
routing_mode = "REGIONAL"
self_link = "https://www.googleapis.com/compute/v1/projects/my-project-id/global/networks/terraform-network"
}
local でビルドした google provider を利用する設定
terraform の設定が期待通りに動かない場合に、local でビルドした google provider を利用できると検証時に便利です。
local ビルド
git clone https://github.com/hashicorp/terraform-provider-google.git
Go 言語でビルドします。
cd ./terraform-provider-google
go build
ビルド成果物
du -h ~/terraform-provider-google/terraform-provider-google
75M /home/vagrant/terraform-provider-google/terraform-provider-google
~/.terraformrc
以下のようなディレクトリとシンボリックリンクを作成します。
mkdir -p ~/.terraform.d/plugin/registry.terraform.io/hashicorp/google/99.99.99/linux_amd64
mkdir -p ~/.terraform.d/plugin-cache
ln -s ~/terraform-provider-google/terraform-provider-google ~/.terraform.d/plugin/registry.terraform.io/hashicorp/google/99.99.99/linux_amd64/terraform-provider-google_v99.99.99
~/.terraformrc を作成します。
provider_installation {
filesystem_mirror {
path = "/home/vagrant/.terraform.d/plugin"
}
direct {
exclude = []
}
}
plugin_cache_dir = "/home/vagrant/.terraform.d/plugin-cache"
terraform init
main.tf の version を更新します。
terraform {
required_providers {
google = {
source = "hashicorp/google"
# version = "3.60.0"
version = "99.99.99"
}
}
}
ロックファイルを削除して init しなおします。
rm .terraform.lock.hcl
terraform init
以下のように .terraform/* にインストールされました。
find .terraform/providers/ -name terraform-provider-google* -follow
.terraform/providers/registry.terraform.io/hashicorp/google/3.60.0/linux_amd64/terraform-provider-google_v3.60.0_x5
.terraform/providers/registry.terraform.io/hashicorp/google/99.99.99/linux_amd64/terraform-provider-google_v99.99.99
応用的な設定例 (Cloud Console および API へのアクセス制限の設定)
注意: BeyondCorp Enterprise の機能を使うため、以下の手順を試すためには GCP における「組織」の登録が必要となります。
サービスアカウントを作成
サービスアカウントは、ある一つのプロジェクトに属します。「組織」にサービスアカウントを作成することはできないため、適当なプロジェクトでサービスアカウントを作成します。
mylab-308012 というプロジェクトで my-service-account-2 を作成すると、以下のようなメールアドレスになります。
my-service-account-2@mylab-308012.iam.gserviceaccount.com
JSON 形式の鍵ファイルをダウンロードしておきます。
「組織」の階層構造を参照する権限の付与
「組織」の「IAM」において、「roles/browser(参照者)」ロールをサービスアカウントに付与します。
組織の階層構造を参照できるようになります。

gcloud auth activate-service-account --key-file ./my-service-account-2.json
gcloud organizations list
DISPLAY_NAME ID DIRECTORY_CUSTOMER_ID
qoosky.io 111111111111 XXXXXXXXX
「組織」のリソースを編集する権限の付与
作成したサービスアカウントを用いて Terraform でリソースを作成する必要があるため、更に「roles/editor(編集者)」ロールも付与します。
editor ロールがあると、組織のリソースを閲覧できるようになります。例えば以下のコマンドがエラーなく実行できます。
gcloud access-context-manager policies list --organization 111111111111
NAME ORGANIZATION TITLE ETAG
486212067009 111111111111 default policy 045d9af982e4e4fa
デフォルトのポリシーが既に作成されている「組織」の場合は上記のように表示されます。「組織」は一つのポリシーしか持てないため、デフォルトのポリシーが存在する場合は terraform でポリシーを作成しようとするとエラーになります。
「アクセスレベル」の作成
「デフォルトのポリシー」が存在しない場合は、以下のように「組織」のポリシーも terraform で管理します。既にデフォルトのポリシーが存在する場合で terraform 管理しない場合は、以下の main.tf の ${google_access_context_manager_access_policy.my-access-policy.name} をデフォルトポリシーのものでハードコーディングします。
main.tf
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "3.60.0"
}
}
}
provider "google" {
credentials = file("./my-service-account-2.json")
}
resource "google_access_context_manager_access_policy" "my-access-policy" {
parent = "organizations/111111111111"
title = "my-access-policy"
}
resource "google_access_context_manager_access_level" "access-level" {
parent = "accessPolicies/${google_access_context_manager_access_policy.my-access-policy.name}"
name = "accessPolicies/${google_access_context_manager_access_policy.my-access-policy.name}/accessLevels/my_ip_restriction"
title = "my_ip_restriction"
basic {
conditions {
ip_subnetworks = [
"123.123.123.123/32"
]
}
}
}
google_access_context_manager_access_level リソースのドキュメントはこちらですが、terraform の google プロバイダは、内部的には GCP REST API を実行しているため、ドキュメントでは把握しづらい情報は、REST API のドキュメントを参照して設定します。
グループの作成
グループを作成します。これにユーザを所属させることで、アクセス制限を行います。サービスアカウントでグループを作成するためには、必要な権限を付与する必要があります。CloudIdentity の場合は「グループ管理者」を付与します。
Cloud Identity 管理コンソールで「管理者ロール」をクリックします。

「グループ管理者」をクリックします。

「サービスアカウントへの割り当て」をクリックします。

サービスアカウントのメールアドレスを入力して追加します。

また、CloudIdentity の顧客ID を確認しておきます。
gcloud organizations list
DISPLAY_NAME ID DIRECTORY_CUSTOMER_ID
qoosky.io 111111111111 CXXXXXXXX
main.tf に以下のリソース定義を追記します。
resource "google_cloud_identity_group" "my-group" {
display_name = "my-ip-restriction-group"
parent = "customers/CXXXXXXXX"
group_key {
id = "my-ip-restriction-group@qoosky.io"
}
labels = {
"cloudidentity.googleapis.com/groups.discussion_forum" = ""
}
}
補足
| アカウントタイプ | ドメイン | Organization Administrator (GCP IAM による cloudidentity.googleapis.com 利用の許可) | Groups Admin (Cloud Identity qoosky.io) | mygroup@qoosky.io 作成 |
|---|---|---|---|---|
| ユーザアカウント | qoosky.io | X | X | X |
| ユーザアカウント | qoosky.io | O | X | O |
| ユーザアカウント | qoosky.io | X | O | O |
| ユーザアカウント | qoosky.io | O | O | O |
| ユーザアカウント | abc.com | O/X | X (権限付与はできません) | X |
| サービスアカウント | xxx.iam.gserviceaccount.com | X | X | X |
| サービスアカウント | xxx.iam.gserviceaccount.com | O | X | X |
| サービスアカウント | xxx.iam.gserviceaccount.com | X | O | X |
| サービスアカウント | xxx.iam.gserviceaccount.com | O | O | O |
アクセスバインディングの作成
作成した「アクセスレベル」と「グループ」の紐付けを設定します。
resource "google_access_context_manager_gcp_user_access_binding" "my-access-binding" {
organization_id = "111111111111"
group_key = trimprefix(google_cloud_identity_group.my-group.id, "groups/")
access_levels = [
google_access_context_manager_access_level.access-level.name,
]
}
補足
最終的に以下のような main.tf となります。
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "3.60.0"
}
}
}
provider "google" {
credentials = file("./my-service-account-2.json")
}
resource "google_access_context_manager_access_policy" "my-access-policy" {
parent = "organizations/111111111111"
title = "my-access-policy"
}
resource "google_access_context_manager_access_level" "access-level" {
parent = "accessPolicies/${google_access_context_manager_access_policy.my-access-policy.name}"
name = "accessPolicies/${google_access_context_manager_access_policy.my-access-policy.name}/accessLevels/my_ip_restriction"
title = "my_ip_restriction"
basic {
conditions {
ip_subnetworks = [
"123.123.123.123/32"
]
}
}
}
resource "google_cloud_identity_group" "my-group" {
display_name = "my-ip-restriction-group"
parent = "customers/CXXXXXXXX"
group_key {
id = "my-ip-restriction-group@qoosky.io"
}
labels = {
"cloudidentity.googleapis.com/groups.discussion_forum" = ""
}
}
resource "google_access_context_manager_gcp_user_access_binding" "my-access-binding" {
organization_id = "111111111111"
group_key = trimprefix(google_cloud_identity_group.my-group.id, "groups/")
access_levels = [
google_access_context_manager_access_level.access-level.name,
]
}
また、アクセス制限できるのは、同じドメイン qoosky.io におけるユーザアカウントのみです。
- サービスアカウントは、グループに含めたとしても制限できません。
- ドメイン部分が
@qoosky.io以外のユーザは、グループに含めたとしても制限できません。- 他のドメインのユーザに qoosky.io 組織内のプロジェクトの権限を与えていたとしても制限できないということになります。
- アクセスバインディングは、有効になるまでに、作成してから最長で24時間かかることがあります。(アクセスレベルの名称等を変更するとすぐに有効になることがあります。)

アクセス制限が有効になると cloud console が使えなくなります。

API も同様です。

うまくいかない場合の動作検証
期待通りに動作しない場合は、Cloud Logging のログを「組織」について確認します。

上記例では、callerIp が IPv6 となっており、IPv4 で設定した許可IP としてアクセスできておらず、Access Denied となっています。自宅や職場のネットワーク設定で IPv6 を利用している場合は注意します。
IPv4 の 0.0.0.0/0 に相当する ::/0 を許可 IP として設定して Access Denied とならなくなる場合は、これが原因です。
関連する gcloud コマンド
グループの情報を調査
gcloud identity groups describe my-ip-restriction-group@qoosky.io
グループ一覧の確認
gcloud identity groups search --organization 111111111111 --labels 'cloudidentity.googleapis.com/groups.discussion_forum'
gcloud は内部的に REST API を実行しています。上記と同様の処理を curl で行うためには以下のようにします。parent を URL エンコーディングする必要があることに注意します。
curl -sS -H "Authorization: Bearer $(gcloud auth print-access-token)" "https://cloudidentity.googleapis.com/v1/groups?parent=customers%2FCXXXXXXXX"
グループを作成できるアカウントであることを gcloud で確認
gcloud identity groups create my-group@qoosky.io --organization 111111111111 --labels 'cloudidentity.googleapis.com/groups.discussion_forum' --with-initial-owner empty
アクセスバインディングを gcloud で作成、削除 (group-key の指定方法に注意)
gcloud access-context-manager cloud-bindings create \
--group-key "04k668n33mb28sl" \
--level accessPolicies/486212067009/accessLevels/my_ip_restriction \
--organization 111111111111
gcloud access-context-manager cloud-bindings delete --binding organizations/111111111111/gcpUserAccessBindings/aAQS-YRTcHRZ1IHJsBBe9kx0Tv1WHPqDpiA7yVtVZI55qrJpu
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- GKE における Node および Pod の autoscaling
Google Kubernetes Engine (GKE) における autoscaling について、用語の意味を整理します。 GKE の機能による Node の autoscaling GKE のクラスタには Standard と Autopilot の二種類が存在します。 Autopilot の場合は Node は Google によって管理されるため、自動で autoscaling され... - Snowflake におけるネットワーク関連の設定
本ページではネットワーク関連の設定について記載します。 Network Policy によるアクセス元 IP 制限 IPv4 で指定します。IPv6 は 2021/9/21 時点では利用できません。 allowed list で許可されていない IP は block されます。 allowed list が /24 等で指定されており、その一部を - VPC Service Controls に関する雑多な事項の整理
VPC Service Controls (VPC-SC) に関する雑多な事項を記載します。 Private Google Access の基本形 Private Google Access は外部 IP を持たない VM のための機能です。VPC の機能ですが、VPC-SC と関連するため基本事項を記載します。 [Private Google Access](ht - AWS IAM Role を GCP から STS 認証で利用する設定例
GCP から AWS IAM Role を利用するための設定例を記載します。 GCP Service Account の作成 Service Account を作成して Unique ID を確認します。 AWS IAM Role の作成 Trust relationship の設定は Web Identity を選択します。Identity Provider - Amazon Comprehend を GCP VPC 内から実行する設定の例 (Public Internet 接続なし)GCP DLP に相当する AWS サービスに Amazon Comprehend が存在します。GCP VPC 内から Public Internet を経由せずに利用する設定の例を記載します。 AWS VPC と GCP VPC の作成 クラウド 項目 値 AWS VPC region ap-northeast-1 AWS VPC CIDR 10.2.0.0/16 AWS ap-north



