Terraform で IAP 設定する
---.icon
2022/3/29 今は internal なものならすぐ作れそう? 今これぐらいでできそう
code:iap.tf
# 現状 terraform から作れるのは internal のみ
resource "google_iap_brand" "project_brand" {
support_email = "pokutuna@hogehoge.ne.jp"
application_title = "pokutunaland"
project = var.project
}
resource "google_iap_client" "gae_client" {
display_name = "iap_client"
brand = google_iap_brand.project_brand.name
}
resource "google_iap_web_type_app_engine_iam_policy" "iap_gae" {
project = var.project
app_id = google_app_engine_application.default.app_id
policy_data = data.google_iam_policy.hogehoge_internal.policy_data
}
data "google_iam_policy" "hogehoge_internal" {
binding {
role = "roles/iap.httpsResourceAccessor"
members = [
"domain:hogehoge.ne.jp",
]
}
}
resource "google_app_engine_application" "default" {
project = var.project
location_id = "asia-northeast1"
iap {
enabled = true
oauth2_client_id = google_iap_client.gae_client.client_id
oauth2_client_secret = google_iap_client.gae_client.secret
}
}
IAP Client、こういう感じにはなる
手でポチポチ作る際には名に IAP 用の OAuth Client 作らなくてよかった気がするが...
https://gyazo.com/988f1e8ae0f5682a0c677fce06d96ed0
GAE の特定の service に対して許可するにはこちらを使う
google_app_engine_standard_app_version.version.service などを使うと GAE のリリースごとになんかしないといけなくてだるい、実際は service程度しか束縛しないだろうし、service は直接そのまま GAE の service 名のようなので以下みたいにしている
code:iap_app_engine_iam.tf
resource "google_iap_app_engine_service_iam_member" "app_admin_iam_member" {
project = var.project
app_id = google_app_engine_application.default.app_id
service = "admin"
role = "roles/iap.httpsResourceAccessor"
member = "user:oneetyan@gmail.com"
}
---.icon
作業ログ、ゴールは Terraform で GAE アプリケーションに GSuite 限定で認証をかけること
準備
Terraform 外
GAE に適当なアプリケーションをデプロイする
Terraform 実行用サービスアカウントを作る
main.tf、variables.tf をちょっとだけ書いて terraform init
variables.tf には project, region, timezone ぐらいを書いてる
backend.tf に backend となる GCS の設定を書いて terraform apply main.tf に backend 設定を書いて再度 terraform init
ローカルの tfstate が GCS に移って用無しになる、.backup に残るけど消す
ここで GCS resource の参照はできない、先に解決されるべきヤツっぽいので変数が使えない(Terraform の実行ステップを説明する語彙がない)
あとはやっていきモード
appengine の app_id がほしい
で必要
project 名を入れときゃよさそうだが一応 tf 上で解決できるようにする
アプリケーションのデプロイは terraform からやるつもりはない
こっちでも IAP の設定できそうだが、OAuth token とかを設定してやりたいわけじゃなくて role や組織の制御でやりたいので違いそう
service に関するリソースが見当たらないけどそういうもの?
google_app_engine_application_service みたいな resource 宣言だけして import して名前で参照したい気もするけど、そういうのはなさそう
code:appengine.tf
resource "google_app_engine_application" "app" {
project = var.project
location_id = var.region
}
これ書いて
$ terraform import google_app_engine_application.app ${プロジェクト名}
初回は GAE Admin API が有効になってないのでエラーになる、出力の URL から有効にする
import できてそう
IAP の設定
どれがどれかわからんが
GAE version 単位で設定したいわけではない
service 単位の resource しかない、GAE 全体でいいんだけど
コンソール上で IAP を設定するには先に OAuth 同意画面(consent screen)を設定する必要ある
OAuth や consent で検索してもどのリソースかわからないけどこれかな? 後回しにしてエラー出るか見てみよう
OAuth 同意画面が internal ならまず組織でフィルタされるので複数 org は行けないはず
切り替えは手動でやるものっぽい
To convert it into an external brands please use the GCP Console.
やってみよう
code:iap.tf
resource "google_iap_app_engine_service_iam_policy" "iap_gae_default" {
project = var.project
app_id = google_app_engine_application.app.app_id
service = "defualt"
policy_data = data.google_iam_policy.heisya_internal.policy_data
}
data "google_iam_policy" "heisya_internal" {
binding {
role = "roles/iap.httpsResourceAccessor"
members = [
"heisya.ne.jp"
]
}
}
plan はうまくいく、apply は 403 でコケる
googleapi: Error 403: The caller does not have permission
うーん編集者なんだけど、同意画面がなくてもこう言ってるだけじゃないのか
一応オーナーにしてみてやってみる
googleapi: Error 404: Requested entity was not found.
エラーコードが変わった...
https://gyazo.com/55476c0b09a3999d688a9ba97866d4f4
これなら行けそう、編集者に含まれてないのかは後で確認したい
→ SA が編集者だからってなんでもあるわけではない
同意画面を作る
先に同意画面を作る
code:iap2.tf
resource "google_iap_brand" "project_brand" {
support_email = "platform@heisya.ne.jp"
application_title = "Hoge Title"
project = var.project
}
うーん
oogleapi: Error 400: Support email is not allowed: platform@heisya.ne.jp
削除や更新の API がない、初回は手で作ってそう
諦めて手で作ろう
brand = OAuth 同意画面という確証はまだ無いけど...
手で作った
import を試みる、beta らしいので google-beta provider が必要
code:iap3_tf
resource "google_iap_brand" "default" {
provider = google-beta
}
これで terraform init して terraform import google_iap_brand.default project_brand
Error: Saw project_brand when the name is expected to have shape projects/{{project}}/brands/{{name}}
はい
どういう name があるのかわからん
API しらべにいく
これでみれそう
https://gyazo.com/a067d223d5dfa7df5ba1d780d3f6c333
code:response.json
{
"brands": [
{
"name": "projects/xxxxxx/brands/xxxxxx",
"supportEmail": "platform@heisya.ne.jp",
"applicationTitle": "Hoge Title"
}
]
}
name は projects/{project_number}/brands/{project_number} になるらしい、し、ししし知らねぇ〜〜〜〜
同意画面で設定した supportEmail と applicationTitle が入ってる
まーこれで import はできるが、API で更新できないし brands の id なり attribute が必要なこともなさそう
terraform import google_iap_brand.default projects/xxxxxx/brands/xxxxxx でできそう
depends_on で参照されてるほうが宣言的だけど、まあ管理しないでいいや...
IAP 設定する
うーんコケる
https://gyazo.com/f1fde9d68b8305e55fc63986d300492d
あーまず GAE 側で IAP 有効にしないといけないのかな?
いやこれは単なる IAP コンソールへのリンクだな
https://gyazo.com/10bc7efd75c374f7fa9d1d784c9ba748
service 単位以前に GAE にやっぱ設定する必要ありそうだなあ
これかな?
これっぽさがある!
members には user: や group: などの prefix が必要
code:iap4.tf
resource "google_iap_web_type_app_engine_iam_policy" "iap_gae" {
project = var.project
app_id = google_app_engine_application.app.app_id
policy_data = data.google_iam_policy.heisya_internal.policy_data
}
data "google_iam_policy" "heisya_internal" {
binding {
role = "roles/iap.httpsResourceAccessor"
members = [
"domain:heisya.ne.jp",
"domain:heisya.com",
]
}
}
こういう感じで
apply うまくいった!
あれ?
https://gyazo.com/70734ec32256b910b29c732386fb5de9
role の設定はできてるが IAP が有効になってない
OAuth 同意画面見に行ったらなんか UI が変わった... えええ...
https://gyazo.com/2d2f2a8f4415dd9be404ac3fb842123b
30分前は古い UI だったんだが!!
デベロッパーの連絡先情報が必須になっていた、他何も変更せず email 連絡先コピペして保存したら通った
IAP のトグル押さずに OK になった
差分出る
再度 plan する
IAP 有効になったことで GAE のリソースに差分が出ている
code:diff
# google_app_engine_application.app will be updated in-place
~ resource "google_app_engine_application" "app" {
auth_domain = "gmail.com"
database_type = "CLOUD_DATASTORE_COMPATIBILITY"
gcr_domain = "asia.gcr.io"
location_id = "asia-northeast1"
serving_status = "SERVING"
url_dispatch_rule = []
... いろいろのいろ ...
feature_settings {
split_health_checks = true
}
- iap {
- enabled = true -> null
- oauth2_client_id = "xxxxxxxxxx.apps.googleusercontent.com" -> null
- oauth2_client_secret_sha256 = (sensitive value)
}
timeouts {}
}
IAP 設定が入った
こういうのどう解決すべきなのかな?
import して上書きする? のはなさそうだから rm して import? いずれにせよ tf に書かないといけないか
iap 自体は optional だけど required が下にあるからいずれにせよ管理しないといけないか
選択肢
app_id ほしかっただけだから管理をやめる
oauth secret も .tf に書く(やりたくない)
これ IAP 有効にしたら GCP 側で勝手に設定してくれるやつだしなあ
まあ一旦消すかあ
terraform state rm 'google_app_engine_application.app'
.tf と app_id 参照しているところを変更(var.project)
plan して差分が出ないのを確認
コンソールでやれば10分で終わる作業なんだよな、管理して気持ちいいだけだなこれ