一,引言
之前我們在使用 Terraform 構築一下 Azure 雲資源的時候,直接將所以需要建立的資源全面寫在 main.tf 這個檔案中,這樣寫主要是為了演示使用,但是在實際的 Terraform 程式碼的整個專案程式碼結構是需要封裝具體的 “Module”,這裡提到了 ”Module“ 也就是新的概念 “Common Module”。“Common Mudule” 其實對於開發來說,其實就是封裝的 ”類庫“,通過傳遞不同的引數,呼叫方法,來實現不同的返回值;同理,terraform 的 common moudle 也是一樣的。
以下是 Terraform 專案結構
--------------------Azure Terraform 系列--------------------
1,Azure Terraform(一)入門簡介
2,Azure Terraform(二)語法詳解
3,Azure Terraform(三)部署 Web 應用程式
4,Azure Terraform(四)狀態檔案儲存
5,Azure Terraform(五)利用Azure DevOps 實現自動化部署基礎資源
6,Azure Terraform(六)Common Module
二,正文
1,Terraform 資源 Moudle 結構定義
按照資源劃分,將每種型別的資源劃分為單獨的 “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. " }
2,資源 Module 引用
將 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 初始化操作,匯入的所有模組的配置
3,如何劃分 Terraform 資源模組
common module 的劃分和封裝沒有固定的標準,我們在劃分和封裝的時候要從多個角度去考慮問題
1,專案太小,只有一個 web 應用程式,是否需要封裝?
2,是否必須嚴格講每個 terraform resource 劃分成單獨的 common module?
3,封裝的 common module 以及 module 引用是否滿足專案架構需求?
所以,劃分、封裝 common module 不是必須的。只要我們能夠清楚的看到實際專案的整體架構需求,是否使用模組化都是有利有弊的。大家要清楚的看到這一點。
完整程式碼請參考文章底部的 github 連結
三,結尾
參考資料:Terraform 官方,azurerm 文件
Terraform_Cnbate_Traffic_Manager github:https://github.com/yunqian44/Terraform_Cnbate_Traffic_Manager
作者:Allen
版權:轉載請在文章明顯位置註明作者及出處。如發現錯誤,歡迎批評指正。