terraform
Last week Hashicorp released version 0.13 of Terraform which from my opinion ended a journey started in 0.12 with the availability of the ‘for’ expressions.
上周,Hashicorp发布了Terraform的0.13版本,以我的观点,该版本以“ for”表达式的可用性结束了从0.12开始的旅程。
Indeed before 0.12 it was arduous to write code that iterates on lists or maps without knowing in advance their depth. ‘for_each’ expression filled a gap in term of code factorization. Actually it was very handy until you write modules which were not supported. Yet if you want your code being reusable writing modules can be of help.
的确,在0.12之前,编写代码在列表或地图上进行迭代而不预先知道其深度是很困难的。 “ for_each”表达式填补了代码分解方面的空白。 实际上,在编写不支持的模块之前,它非常方便。 但是,如果您希望代码可重用,则编写模块可能会有所帮助。
Version 0.13 finally offered to use ‘for_each’ in modules so I wanted to demonstrate how to use it in the context of Azure and more precisely with Azure AD. For that, we’re going to dynamicaly create AAD users with the azuread provider. As an input we will use a list of usernames that can be of one to many elements.
版本0.13最终提供了在模块中使用'for_each'的功能,因此我想演示如何在Azure的上下文中以及更精确地在Azure AD中使用它。 为此,我们将使用azuread提供程序动态创建AAD用户。 作为输入,我们将使用可以包含一个或多个元素的用户名列表。
First things first, let’s create a terraform projet with a standardized module structure. Here’s how your project folder should look like :
首先,让我们创建具有标准化模块结构的terraform项目。 项目文件夹的外观如下所示:
/add-users
|-- /modules
| |-- /aad-user
| |-- main.tf
| |-- variables.tf
|-- main.tf
|-- variables.tf
Let’s take a look at the aad-user module files:
让我们看一下aad-user模块文件:
resource "azuread_user" "user" {
user_principal_name = "${var.username}@${var.domain_name}"
display_name = var.username
mail_nickname = var.username
password = var.password
force_password_change = true
}
variable "username" {
type = string
description = "Username"
}
variable "domain_name" {
type = string
description = "AAD domain name"
}
variable "password" {
type = string
description = "Temporary password"
}
With those two files we should be able to create one single azuread_user instance but we want to do more than that and instead call this module as many times as we have users to create. So let’s call this module and loop on a list of users.
使用这两个文件,我们应该能够创建一个azuread_user实例,但是我们想做更多的事情,而是根据需要创建的用户多次调用此模块。 因此,让我们调用此模块并在用户列表上循环。
Let’s create a variables.tf in the project root folder with a list of string containing usernames and a string containing the temporary password (this is for demonstrating purpose as you should rather generate random passwords and export them as output but this won’t be covered in this article):
让我们在项目根文件夹中创建一个variables.tf ,其中包含一个包含用户名的字符串和一个包含临时密码的字符串的列表(这是出于演示目的,因为您应该生成随机密码并将其导出为输出,但这不会涉及在这篇文章中):
variable "userlist" {
type = list(string)
default = ["john", "nicolas"]
}
variable "password" {
type = string
description = "Temporary password"
default = "Str0ng3stP@sswd3ver!"
}
Then create a main.tf and call the module :
然后创建一个main.tf并调用模块:
terraform {
required_version = ">=0.13"
}
provider "azuread" {
version = ">=0.11.0"
}
data "azuread_domains" "aad_domains" {
only_default = true
}
module "aad-user" {
source = "./modules/aad-user"
for_each = toset(var.userlist)
username = each.value
password = var.password
domain_name = data.azuread_domains.aad_domains.domains[0].domain_name
}
Watch the for_each line and see that a toset() function is needed as for_each only accepts sets or maps.
观看for_each行,并看到需要一个toset()函数,因为for_each仅接受集合或映射。
Watch the username line and the each.value expression that loops on the user list.
注意用户名行和在用户列表上循环的each.value表达式。
For the domain_name the data block automatically pulls the default from your connected AAD tenant.
对于domain_name ,数据块会自动从您连接的AAD租户中提取默认值。
Now let’s terraform this:
现在让我们将其地形化:
az login
terraform init
terraform plan
terraform applyApply complete! Resources: 2 added, 0 changed, 0 destroyed.
That’s it! We’ve created two new users in our Azure AD tenant with a module that can be shared across templates to create one to many users.
而已! 我们在Azure AD租户中创建了两个新用户,分别是 一个可以在模板之间共享以创建一对多用户的模块。
terraform