试试 Terraform 的 Keycloak Provider
首先
我发现在Terraform中存在Keycloak提供者,所以我想试试。在Keycloak中,存在导入/导出Realm信息的功能,但由于使用JSON处理,可读性稍差。Terraform – Keycloak提供者允许使用HCL以声明方式定义Realm设置,我个人觉得这很棒。
这篇文章是在假设已经安装好Keycloak的基础上进行撰写的。为了更专注于Keycloak提供者,我们将省略有关Terraform的基础知识和关于Keycloak的解释,以及涉及到的标准规范(如OpenID Connect等)的解释。
Terraform – Keycloak Provider 的身份验证
在设置Keycloak的配置之前,Terraform-Keycloak Provider需要进行身份验证。有两种方法可以实现:一种是使用admin-cli客户端,另一种是为Terraform创建一个OIDC(OpenID Connect)客户端。
客户端凭证授权设置(推荐)
根据所述,建议创建一个OIDC客户端,因此我们将为Terraform创建一个客户端。
本次操作將使用 Terraform 創建 Realm,因此在主要 Realm 上創建以下客戶端。如果只需要在相應的 Realm 中進行操作,請創建一個 OIDC 客戶端。
通用设置
-
- Client type: OpenID Connect
-
- Client ID: terraform
-
- Name: Terraform
-
- Description: Terraform Keycloak Provider
- Always display in console: off
能力配置
-
- Client authentication: On
-
- Authorization: Off
- Authentication flow: Service accounts role にチェック
这是为了实现OpenID Connect中的客户端凭证流而进行的设置。
保存后,可以在Credentials选项卡中找到生成的客户端密钥,必须将其记下。
接下来,给该客户分配管理员角色。
如果想要限制分配角色,请参考”分配角色”进行设置。
写Terraform配置文件
provider "keycloak" {
client_id = var.client_id
client_secret = var.client_secret
url = var.url
}
terraform {
required_providers {
keycloak = {
source = "mrparkers/keycloak"
version = ">= 4.0.0"
}
}
}
variable "client_id" {
description = "Keycloak client_id for Terraform"
}
variable "client_secret" {
description = "Keycloak client_secret for Terraform"
}
variable "url" {
description = "Keycloak URL"
}
请随意传入适当的输入变量,可以是环境变量或*.tfvars文件。
由於Keycloak Provider與Keycloak之間的驗證已經完成,現在為了進行操作確認,讓我們創建一個Realm。
#####
# Realm
locals {
realm_id = "example-realm" # ご自由な名前でどうぞ
}
resource "keycloak_realm" "realm" {
realm = local.realm_id
}
开始
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding mrparkers/keycloak versions matching ">= 4.0.0"...
- Installing mrparkers/keycloak v4.3.1...
- Installed mrparkers/keycloak v4.3.1 (self-signed, key ID C50867915E116CD2)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
计划
$ terraform plan -var-file variables.tfvars
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:
# keycloak_realm.realm will be created
+ resource "keycloak_realm" "realm" {
+ access_code_lifespan = (known after apply)
+ access_code_lifespan_login = (known after apply)
+ access_code_lifespan_user_action = (known after apply)
+ access_token_lifespan = (known after apply)
+ access_token_lifespan_for_implicit_flow = (known after apply)
+ action_token_generated_by_admin_lifespan = (known after apply)
+ action_token_generated_by_user_lifespan = (known after apply)
+ browser_flow = (known after apply)
+ client_authentication_flow = (known after apply)
+ client_session_idle_timeout = (known after apply)
+ client_session_max_lifespan = (known after apply)
+ direct_grant_flow = (known after apply)
+ docker_authentication_flow = (known after apply)
+ duplicate_emails_allowed = (known after apply)
+ edit_username_allowed = (known after apply)
+ enabled = true
+ id = (known after apply)
+ internal_id = (known after apply)
+ login_with_email_allowed = (known after apply)
+ oauth2_device_code_lifespan = (known after apply)
+ oauth2_device_polling_interval = (known after apply)
+ offline_session_idle_timeout = (known after apply)
+ offline_session_max_lifespan = (known after apply)
+ offline_session_max_lifespan_enabled = false
+ realm = "example-realm"
+ refresh_token_max_reuse = 0
+ registration_allowed = (known after apply)
+ registration_email_as_username = (known after apply)
+ registration_flow = (known after apply)
+ remember_me = (known after apply)
+ reset_credentials_flow = (known after apply)
+ reset_password_allowed = (known after apply)
+ revoke_refresh_token = false
+ ssl_required = "external"
+ sso_session_idle_timeout = (known after apply)
+ sso_session_idle_timeout_remember_me = (known after apply)
+ sso_session_max_lifespan = (known after apply)
+ sso_session_max_lifespan_remember_me = (known after apply)
+ user_managed_access = false
+ verify_email = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
申请
$ terraform apply -var-file variables.tfvars
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:
# keycloak_realm.realm will be created
+ resource "keycloak_realm" "realm" {
+ access_code_lifespan = (known after apply)
+ access_code_lifespan_login = (known after apply)
+ access_code_lifespan_user_action = (known after apply)
+ access_token_lifespan = (known after apply)
+ access_token_lifespan_for_implicit_flow = (known after apply)
+ action_token_generated_by_admin_lifespan = (known after apply)
+ action_token_generated_by_user_lifespan = (known after apply)
+ browser_flow = (known after apply)
+ client_authentication_flow = (known after apply)
+ client_session_idle_timeout = (known after apply)
+ client_session_max_lifespan = (known after apply)
+ direct_grant_flow = (known after apply)
+ docker_authentication_flow = (known after apply)
+ duplicate_emails_allowed = (known after apply)
+ edit_username_allowed = (known after apply)
+ enabled = true
+ id = (known after apply)
+ internal_id = (known after apply)
+ login_with_email_allowed = (known after apply)
+ oauth2_device_code_lifespan = (known after apply)
+ oauth2_device_polling_interval = (known after apply)
+ offline_session_idle_timeout = (known after apply)
+ offline_session_max_lifespan = (known after apply)
+ offline_session_max_lifespan_enabled = false
+ realm = "example-realm"
+ refresh_token_max_reuse = 0
+ registration_allowed = (known after apply)
+ registration_email_as_username = (known after apply)
+ registration_flow = (known after apply)
+ remember_me = (known after apply)
+ reset_credentials_flow = (known after apply)
+ reset_password_allowed = (known after apply)
+ revoke_refresh_token = false
+ ssl_required = "external"
+ sso_session_idle_timeout = (known after apply)
+ sso_session_idle_timeout_remember_me = (known after apply)
+ sso_session_max_lifespan = (known after apply)
+ sso_session_max_lifespan_remember_me = (known after apply)
+ user_managed_access = false
+ verify_email = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
keycloak_realm.realm: Creating...
keycloak_realm.realm: Creation complete after 5s [id=example-realm]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
当查看 Realm 的列表时,可以确认 example-realm 已被包含在内。
结束了
我使用Terraform Keycloak Provider将Keycloak的配置转化为基础设施代码。
当我尝试确认时,我发现有许多资源可用。下次我想使用Keycloak Provider来创建用于Grafana的SSO的Realm、Group、Member和Client等。