在Terraform 2.0中使用HCL语言可以非常方便地管理基础设施。这不仅包括创建和管理资源,还包括通过创建和分配存储主体来访问这些资源。在Terraform的旧版本中,可以通过使用azurerm_azuread_application和其他元素来实现这一点。之前在GitHub上的Kubernetes模板中已经实现了这一点。现在,随着Terraform v2.0的发布,包括移除所有Azure AD元素并将它们移动到它们自己的provider,问题变成了“这将如何改变模板?”下面是一个示例,它展示了如何创建一个带有随机密码的服务主体,并为keyvault创建一个访问策略。
首先,来看一个示例代码,它展示了如何创建一个服务主体,并为keyvault创建一个访问策略。代码如下:
resource "random_string" "kub-rs-pd-kv" {
length = 32
special = true
}
data "azurerm_subscription" "current" {
subscription_id = "${var.subscription_id}"
}
resource "azurerm_azuread_application" "kub-ad-app-kv1" {
name = "${format("%s%s%s-KUB1", upper(var.environment_code), upper(var.deployment_code), upper(var.location_code))}"
available_to_other_tenants = false
oauth2_allow_implicit_flow = true
}
resource "azurerm_azuread_service_principal" "kub-ad-sp-kv1" {
application_id = "${azurerm_azuread_application.kub-ad-app-kv1.application_id}"
}
resource "azurerm_azuread_service_principal_password" "kub-ad-spp-kv" {
service_principal_id = "${azurerm_azuread_service_principal.kub-ad-sp-kv1.id}"
value = "${element(random_string.kub-rs-pd-kv.*.result, count.index)}"
end_date = "2020-01-01T01:02:03Z"
}
resource "azurerm_key_vault" "kub-kv" {
name = "${var.environment_code}${var.deployment_code}${var.location_code}lkub-kv1"
location = "${var.azure_location}"
resource_group_name = "${azurerm_resource_group.management.name}"
sku {
name = "standard"
}
tenant_id = "${var.keyvault_tenantid}"
access_policy {
tenant_id = "${var.keyvault_tenantid}"
object_id = "${azurerm_azuread_service_principal.kub-ad-sp-kv1.id}"
key_permissions = ["get"]
secret_permissions = ["get"]
}
access_policy {
tenant_id = "${var.keyvault_tenantid}"
object_id = "${azurerm_azuread_service_principal.kub-ad-sp-kv1.id}"
key_permissions = ["create"]
secret_permissions = ["set"]
}
depends_on = ["azurerm_role_assignment.kub-ad-sp-ra-kv1"]
}
接下来,来看一下在新的provider下,如何更新代码以生成一个带有随机密码的服务主体。代码如下:
provider "azuread" {
version = ">=0.7.0"
}
resource "random_string" "cds-rs-pd-kv" {
length = 32
special = true
}
resource "azuread_application" "cds-ad-app-kv1" {
name = format("%s-%s%s-cds1", var.project_name, var.deployment_code, var.environment_code)
oauth2_allow_implicit_flow = true
}
resource "azuread_service_principal" "cds-ad-sp-kv1" {
application_id = azuread_application.cds-ad-app-kv1.application_id
}
resource "azuread_service_principal_password" "cds-ad-spp-kv" {
service_principal_id = azuread_service_principal.cds-ad-sp-kv1.id
value = random_string.cds-rs-pd-kv.result
end_date = "2020-01-01T01:02:03Z"
}
可以看到,代码变得更加简洁,不再使用${}进行字符串插值,资源也变得更加清晰。那么,接下来的问题是如何将这个服务主体连接到代码中,以将其分配给keyvault的访问策略。
可以通过以下代码实现这一点,该代码位于同一目录中的不同文件中:
resource "azurerm_resource_group" "cds-configuration-rg" {
name = format("%s-Configuration", var.group_name)
location = var.location
}
data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "cds-kv" {
name = format("%s-%s%s-kv", var.project_name, var.deployment_code, var.environment_code)
location = var.location
resource_group_name = azurerm_resource_group.cds-configuration-rg.name
enabled_for_disk_encryption = true
tenant_id = data.azurerm_client_config.current.tenant_id
soft_delete_enabled = true
purge_protection_enabled = false
sku_name = "standard"
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
key_permissions = ["create", "get"]
secret_permissions = ["set", "get", "delete"]
}
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = azuread_service_principal.cds-ad-sp-kv1.id
key_permissions = ["get"]
secret_permissions = ["get"]
}
}