使用模块对相关资源进行分组
你已开始使用 Bicep 模板来完成一些最新的产品发布,结果非常成功。 由于你已在模板文件中声明了资源,因此你可以快速部署新的玩具发布资源,而无需在 Azure 门户中手动配置资源。
IT 经理可以看到你的 Bicep 代码变得越来越复杂,并且定义了越来越多的资源,因此,他们询问你能否使代码进一步模块化。 你可以为部署的不同部分创建单独的 Bicep 文件(称为“模块”)。 主 Bicep 模板可以引用这些模块。 在后台,模块将被转译到单个 JSON 模板中以进行部署。
模块也是一种使 Bicep 代码更便于重用的方法。 你可以有单个 Bicep 模块,许多其他 Bicep 模板都使用它。
你还经常需要从 Bicep 模块和模板发出输出。 输出是你的 Bicep 代码将数据发送回启动部署的任何用户或对象的一种方式。 我们先看一下输出。
注意
本单元中显示的命令用于说明概念。 请暂时不要运行这些命令。 稍后你将练习在此处学到的知识。
Outputs
用户可以手动部署 Bicep 模板,或者某种自动化发布过程也可以部署它们。 无论采用哪种方式,从模板中获得一些数据是很常见的,你需要将这些数据发送回执行模板部署的任何用户或对象。
下面是一些可能需要从模板部署获取信息的示例场景:
- 你创建了一个 Bicep 模板来部署虚拟机,需要获取公共 IP 地址,以便可以通过 SSH 连接到计算机。
- 你创建了一个 Bicep 模板,该模板接受一组参数,例如环境名称和应用程序名称。 该模板使用表达式为其部署的 Azure 应用服务应用命名。 需要输出模板已部署的应用名称,以便在部署管道中使用它来发布应用程序二进制文件。
可以为这些场景使用输出。 若要在 Bicep 模板中定义输出,请使用 output
关键字,如下所示:
output appServiceAppName string = appServiceAppName
输出定义包括几个关键部分:
output
关键字告诉 Bicep 你正在定义输出。appServiceAppName
是输出的名称。 当有人成功部署模板时,输出值将包含你指定的名称,这样他们就可以访问所期望的值。string
是输出类型。 Bicep 输出支持与参数相同的类型。- 必须为每个输出指定一个值。 与参数不同的是,输出始终需要具有值。 输出值可以是表达式、对参数或变量的引用,也可以是在文件中部署的资源的属性。
提示
输出可以使用与变量和参数相同的名称。 如果你在一个变量中构造一个复杂的表达式以在模板资源中使用,并且还需要将变量的值公开为输出,那么这种约定就会很有帮助。
下面是输出的另一个示例。 此输出将它的值设置为公共 IP 地址资源的完全限定的域名 (FQDN)。
output ipFqdn string = publicIPAddress.properties.dnsSettings.fqdn
提示
尝试使用资源属性作为输出,而不是对资源的行为进行假设。 例如,如果需要为应用服务应用的 URL 生成输出,请使用应用的 defaultHostName
属性,而不是自行为 URL 创建字符串。 有时候这些假设在不同环境中无效,或者资源会更改它们的工作方式,所以让资源告诉你它自己的属性会更安全。
注意
不要为机密值(如连接字符串或密钥)创建输出。 具有资源组访问权限的任何人都可以从模板读取输出。 你还可以使用其他方法来访问机密资源属性,我们将在后面的模块中介绍这些方法。
定义模块
使用 Bicep 模块,可以通过创建可组合成一个模板的较小单元来组织和重用 Bicep 代码。 任何 Bicep 模板都可由另一个模板用作模块。 在此学习模块中,你已经创建了 Bicep 模板。 这意味着你已经创建了可用作 Bicep 模块的文件!
假设你有一个 Bicep 模板,该模板为解决方案 A 部署应用程序、数据库和网络资源。你可以将此模板拆分为三个模块,每个模块都关注自己的一组资源。 作为奖励,现在也可以将其他模板中的模块重新用于其他解决方案;因此,当你为解决方案 B 开发模板,而该模板具有与解决方案 A 类似的网络要求时,可以重复使用网络模块。
如果需要让模板包含对模块文件的引用,请使用 module
关键字。 模块定义与资源声明类似,但不包括资源类型和 API 版本,而是使用模块的文件名:
module myModule 'modules/mymodule.bicep' = {
name: 'MyModule'
params: {
location: location
}
}
我们来仔细看看此模块定义中的一些关键部分:
module
关键字告诉 Bicep,你将使用另一个 Bicep 文件作为模块。- 与资源一样,模块也需要符号名称,例如
myModule
。 当你在模板的其他部分引用模块的输出时,就会使用符号名称。 modules/mymodule.bicep
是模块文件的路径,相对于模板文件。 请记住,模块文件只是常规的 Bicep 文件。- 与资源一样,
name
属性是必需的。 Azure 使用模块名称,因为它会为模板文件中的每个模块创建单独的部署。 这些部署具有可用于识别它们的名称。 - 你可以使用
params
关键字指定模块的任何参数。 在模板中设置每个参数的值时,可以使用表达式、模板参数、变量、模板中部署的资源的属性,以及其他模块的输出。 Bicep 将自动理解资源之间的依赖关系。
模块和输出
与模板一样,Bicep 模块也可以定义输出。 在模板中将模块链接在一起是很常见的。 在这种情况下,一个模块的输出可以是另一个模块的参数。 通过一起使用模块和输出,可以创建功能强大且可重用的 Bicep 文件。
设计模块
优秀的 Bicep 模块遵循一些关键原则:
模块应有明确的用途。 你可以使用模块来定义与你的解决方案的特定部分相关的所有资源。 例如,你可以创建一个模块,其中包含用于监视应用程序的所有资源。 还可以使用一个模块来定义一组同属的资源,比如你所有的数据库服务器和数据库。
不要将每个资源置于其自己的模块中。 不应为部署的每个资源创建单独的模块。 如果你有一个资源具有许多复杂属性,那么将该资源放入自己的模块可能有意义,但一般情况下,模块最好合并多个资源。
模块应有明确的参数和有意义的输出。 考虑模块的用途。 考虑模块是否应处理参数值,或者父模板是否应处理参数值,然后将单个值传递给模块。 同样,考虑模块应返回的输出,并确保它们对将使用模块的模板有用。
模块应尽可能独立。 如果某个模块需要使用变量来定义模块的一部分,则该变量通常应包含在模块文件中,而不是父模板中。
模块不应输出机密。 与模板一样,不要为机密值(如连接字符串或密钥)创建模块输出。