GCSバケットへのアクセスに対してip制限を設定する機能ができたので試してみる。dbt docsのhtmlをホスティングして、アクセスしてみた。現状はpre-GAの機能
手順としては公開バケットを作成、ip制限の設定をし、dbt docs generateしてhtmlファイルの閲覧ができるか確認した
環境
- dbt: 1.9.0
- gcloud SDK: 532.0.0
- gcloud alpha 2025.03.29
実装
terraform定義
実際のipアドレスにはPCのグローバルipアドレスを設定している。記事中の値は適当に設定している
- 7/27追記
terraformのgcs resourceで設定がされたため。そちらの形式で設定
allow_all_service_agent_accessをtrueにしておくと、ip filterの設定を無視してサービスエージェント経由でアクセスできるようになる
resource "google_storage_bucket" "dbt_docs_bucket" {
name = "dbt-docs"
location = "us-central1"
storage_class = "STANDARD"
force_destroy = true
labels = {
managed_by = "terraform"
}
website {
main_page_suffix = "static_index.html"
}
ip_filter {
mode = "Enabled"
allow_all_service_agent_access = true
public_network_source {
allowed_ip_cidr_ranges = [
"210.0.0.0/24"
]
}
}
}
resource "google_storage_bucket_iam_member" "member" {
provider = google
bucket = google_storage_bucket.dbt_docs_bucket.name
role = "roles/storage.objectViewer"
member = "allUsers"
}
旧:terraformでの定義
null_resource、知らなかったけどclaudeが教えてくれた
resource "google_storage_bucket" "dbt_docs_bucket" {
name = "dbt-docs"
location = "us-central1" // ap-northeast-1は対象外 // var.region
storage_class = "STANDARD"
force_destroy = true
labels = {
managed_by = "terraform"
}
website {
main_page_suffix = "static_index.html"
}
}
resource "google_storage_bucket_iam_member" "member" {
provider = google
bucket = google_storage_bucket.dbt_docs_bucket.name
role = "roles/storage.objectViewer"
member = "allUsers"
}
resource "null_resource" "gcs_ip_filter" {
provisioner "local-exec" {
command = <<EOT
set -e
echo '{
"mode": "Enabled",
"publicNetworkSource": {
"allowedIpCidrRanges": [
"210.0.0.0/24"
]
}
}' > ip_filter.json
gcloud alpha storage buckets update gs://${google_storage_bucket.dbt_docs_bucket.name} --ip-filter-file=ip_filter.json
rm ip_filter.json
EOT
}
depends_on = [google_storage_bucket.dbt_docs_bucket]
}
terraform apply
したあと、ipフィルターが設定されていることを確認する
gcloud alpha storage buckets describe gs://dbt-docs --format="default(ip_filter_config)"
ip_filter_config:
mode: Enabled
publicNetworkSource:
allowedIpCidrRanges:
- "210.0.0.0/24"
一応providerのファイルも
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
variable "project_id" {
type = string
default = "project_id"
}
variable "region" {
type = string
default = "asia-northeast1"
}
terraform apply
したあと、ipフィルターが設定されていることを確認する
gcloud alpha storage buckets describe gs://dbt-docs --format="default(ip_filter_config)"
ip_filter_config:
allowAllServiceAgentAccess: true
mode: Enabled
publicNetworkSource:
allowedIpCidrRanges:
- 210.155.75.179/32
dbt docs upload
dbtプロジェクトはすでにあるものを使う。コマンドを実行すると単一の静的ファイルstatic_index.htmlがtargetディレクトリ以下に生成される
生成、uploadのコマンドは以下
dbt docs generate --static
gloud storage cp ./target/static_index.html gs://dbt-docs/
エンドポイントは、コンソールからGCSオブジェクトのオーバーフローメニュー(︙)より公開URLをコピーした値
https://storage.googleapis.com/dbt-docs/static_index.html
アクセス可能な場合は表示される
設定範囲に含まれないipアドレスからアクセスを試すために cloud shellからコマンド実行してみると、アクセス拒否された。エラーメッセージがちゃんとしている
There is an IP filtering condition that is preventing access to the resource
# Welcome to Cloud Shell! Type "help" to get started.
# Use `gcloud config set project [PROJECT_ID]` to change to a different project.
# y@cloudshell:~ (free)$ curl -XGET https://storage.googleapis.com/dbt-docs/static_index.html
# <?xml version='1.0' encoding='UTF-8'?><Error><Code>AccessDenied</Code><Message>Access denied.</Message><Details>There is an IP filtering condition that is preventing access to the resource.</Deta
注意点として、ipフィルターを設定するとIPアドレス以外での実行はコンソールやcloud経由でも受け付けなくなる。IAM権限よりも強い?らしい。つまりバケットの編集や更新ができなくなる
また、allUsers
なのでコンソール画面でも以下warningが表示される
公開アクセス インターネットに公開
ip制限がIAM roleよりも先に及ぶこと、コンソールからip制限の設定が確認できないなど、現時点で少し使いづらい部分はあるが、社内外に公開したい場合などには便利そう
サービスエージェントを使ってcloudbuildからアクセス
ip制限すると、CI上からgcsにアクセスさせるのが難しい gcpであれば、サービスエージェント経由でアクセス可能になるのでcodebuild経由で実現できる サービスアカウントもできるようにしてほしかったが、そいうわけにもいかないよう あと、サービスエージェントになりすまして実行などもできなかった
- 実装、結果
適当にcatさせる
# cloudbuild.yml
steps:
- name: 'gcr.io/google.com/cloudsdktool/google-cloud-cli'
entrypoint: 'gcloud'
args:
- 'storage'
- 'cat'
- 'gs://dbt-docs/static_index.html'
gcloud builds submit --config cloudbuild.yml .
logは以下のようになる
...
Digest: sha256:942d69f18e4656df2108c792b34f5e6308e1d30bef1deadc8fd9a1ee1b01b641
Status: Downloaded newer image for gcr.io/google.com/cloudsdktool/google-cloud-cli:latest
gcr.io/google.com/cloudsdktool/google-cloud-cli:latest
<!doctype html>
<html dir="ltr" lang="en-US" ng-app="dbt"
class="no-flash video supports no-touchevents formvalidation webgl no-cssgridlegacy cssgrid cssfilters objectfit object-fit click landscape videoautoplay loaded">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,initial-scale=1" />
<title>dbt Docs</title>