参考资料:Terraform 官方,azurerm 文档
Terraform_Cnbate_Traffic_Manager github://github.com/yunqian44/Terraform_Cnbate_Traffic_Manager
作者:Allen
版权:转载请在文章明显位置注明作者及出处。如发现错误,欢迎批评指正。
之前我们在使用 Terraform 构筑一下 Azure 云资源的时候,直接将所以需要创建的资源全面写在 main.tf 这个文件中,这样写主要是为了演示使用,但是在实际的 Terraform 代码的整个项目代码结构是需要封装具体的 “Module”,这里提到了 ”Module“ 也就是新的概念 “Common Module”。“Common Mudule” 其实对于开发来说,其实就是封装的 ”类库“,通过传递不同的参数,调用方法,来实现不同的返回值;同理,terraform 的 common moudle 也是一样的。
以下是 Terraform 项目结构
——————–Azure Terraform 系列——————–
按照资源划分,将每种类型的资源划分为单独的 “Common Moudle”,比方 “资源组”,“流量管理配置”,“Web 应用程序”……
mian.tf:不是项目的入口,该文件中包含了特定资源中的通用资源文件。
resource "azurerm_traffic_manager_profile" "cnbate_traffic_manager_profile" { name = var.traffic_manager_name resource_group_name = var.resource_group_name traffic_routing_method = var.traffic_routing_method dns_config { relative_name = var.relative_name ttl = var.ttl } monitor_config { protocol = var.protocol port = var.port path = var.path interval_in_seconds = var.interval_in_seconds timeout_in_seconds = var.timeout_in_seconds tolerated_number_of_failures = var.tolerated_number_of_failures } tags = var.tags } resource "azurerm_traffic_manager_endpoint" "cnbate_traffic_manager_endpoint" { count = var.enable_traffic_manager_endpoint && var.traffic_manager_endpoint_count > 0 ? var.traffic_manager_endpoint_count : 0 name = element(var.traffic_manager_endpoint_names, count.index) resource_group_name = var.resource_group_name profile_name = azurerm_traffic_manager_profile.cnbate_traffic_manager_profile.name target_resource_id = element(var.target_resource_ids, count.index) type = var.traffic_manager_endpoint_type geo_mappings = element(var.geo_mappings, count.index) }
outputs.tf :包含部署输出变量的定义
################################ traffic manager profile ################################ output "traffic_manager_profile_name" { value = azurerm_traffic_manager_profile.cnbate_traffic_manager_profile.name } output "traffic_manager_profile_id" { value = azurerm_traffic_manager_profile.cnbate_traffic_manager_profile.id } ################################ traffic manager profile ################################ output "azurerm_traffic_manager_endpoint_names" { value = azurerm_traffic_manager_endpoint.cnbate_traffic_manager_endpoint.*.name } output "azurerm_traffic_manager_endpoint_ids" { value = azurerm_traffic_manager_endpoint.cnbate_traffic_manager_endpoint.*.id }
variables.tf:包含了当前资源所封装的变量的定义
################################ traffic manager profile ################################ variable "traffic_manager_name" { type = string description = "(required)The name of the traffic manager profile" } variable "resource_group_name" { type = string description = "The Name which should be used for this Resource Group. Changing this forces a new Resource Group to be created." } variable "traffic_routing_method" { type = string description = "(required) Specifies the algorithm used to route traffic" } variable "relative_name" { type = string description = "(required) The relative domain name, this is combined with the domain name used by Traffic Manager to form the FQDN which is exported as documented below." } variable "ttl" { type = number description = "(Required) The TTL value of the Profile used by Local DNS resolvers and clients" } variable "protocol" { type = string default = "http" description = " (required) The protocol used by the monitoring checks, supported values are HTTP, HTTPS and TCP." } variable "port" { type = number default = 80 description = "(required) The port number used by the monitoring checks." } variable "path" { type = string default = "/" description = " (optional) The path used by the monitoring checks. Required when protocol is set to HTTP or HTTPS - cannot be set when protocol is set to TCP." } variable "interval_in_seconds" { type = number default = 30 description = "(optional) The interval used to check the endpoint health from a Traffic Manager probing agent." } variable "timeout_in_seconds" { type = number default = 10 description = "(optional) The amount of time the Traffic Manager probing agent should wait before considering that check a failure when a health check probe is sent to the endpoint. " } variable "tolerated_number_of_failures" { type = string default = 3 description = "(optional) The number of failures a Traffic Manager probing agent tolerates before marking that endpoint as unhealthy. Valid values are between 0 and 9." } variable "tags" { type = map(string) description = "(optional) A mapping of tags to assign to the resource." } ################################ traffic manager endpoint ################################ variable "enable_traffic_manager_endpoint" { type = bool default = false description = "(required) whether to create traffic manager endpoint" } variable "traffic_manager_endpoint_count" { type = number default = 0 description = "(required) number of create traffic manager endpoint" } variable "traffic_manager_endpoint_names" { type = list(string) description = "(required) The name of the Traffic Manager endpoint." } variable "target_resource_ids" { type = list(string) description = " (optional) The resource id of an Azure resource to target. This argument must be provided for an endpoint of type azureEndpoints or nestedEndpoints." } variable "traffic_manager_endpoint_type" { type = string description = "(required) The Endpoint type, must be one of: 1:azureEndpoints,2:externalEndpoints,3:nestedEndpoints" } variable "geo_mappings" { type = list(list(string)) description = "(Optional) A list of Geographic Regions used to distribute traffic, such as WORLD, UK or DE. " }
将 terraform 项目所封装的 common module 在一个主 mian.tf 进行引用的时候,使用 module
根据模块的位置以及使用该模块的位置,该 source 参数可能有所不同
module "cnbate_Web_app" {
source = "../module/web_app"
app_service_locations = [local.location_eastAsia, local.location_southeastAsia]
resource_group_name = data.azurerm_resource_group.cnbate_resource_group.name
enable = var.enable
enable_app_service_plan = var.enable_app_service_plan
app_service_plan_count = var.app_service_plan_count
app_service_plan_names = var.app_service_plan_names
app_service_plans = var.app_service_plans
enable_app_service = var.enable_app_service
app_service_count = var.app_service_count
app_service_names = var.app_service_names
app_settings = var.app_settings
}
如果模块之间由相互依赖引用,则通过 “module” 引用的方式来建立关系,同时 terraform apply 在执行部署计划的时候,terraform 也会遵循这个依赖关系先后创建资源
module "cnbate_traffic_manager" {
source = "../module/traffic_manager_profile"
traffic_manager_name = var.traffic_manager_name
resource_group_name = data.azurerm_resource_group.cnbate_resource_group.name
traffic_routing_method = var.traffic_routing_method
relative_name = var.relative_name
ttl = var.ttl
tags = var.tags
enable_traffic_manager_endpoint = var.enable_traffic_manager_endpoint
traffic_manager_endpoint_count = var.traffic_manager_endpoint_count
traffic_manager_endpoint_names = var.traffic_manager_endpoint_names
target_resource_ids = module.cnbate_Web_app.azurerm_app_service_ids
traffic_manager_endpoint_type = var.traffic_manager_endpoint_type
geo_mappings = var.geo_mappings
}
注意,一旦依赖关系在 common module 阶段发生改变的时候,就需要重新执行 terraform init 初始化操作,导入的所有模块的配置
common module 的划分和封装没有固定的标准,我们在划分和封装的时候要从多个角度去考虑问题
1,项目太小,只有一个 web 应用程序,是否需要封装?
2,是否必须严格讲每个 terraform resource 划分成单独的 common module?
3,封装的 common module 以及 module 引用是否满足项目架构需求?
所以,划分、封装 common module 不是必须的。只要我们能够清楚的看到实际项目的整体架构需求,是否使用模块化都是有利有弊的。大家要清楚的看到这一点。
完整代码请参考文章底部的 github 链接
参考资料:Terraform 官方,azurerm 文档
Terraform_Cnbate_Traffic_Manager github://github.com/yunqian44/Terraform_Cnbate_Traffic_Manager
作者:Allen
版权:转载请在文章明显位置注明作者及出处。如发现错误,欢迎批评指正。