咱們都知道在執行部署計劃以後,當前目錄中就產生了名叫 「terraform.states」 的 Terraform 的狀態文件,該文件中記錄了已部署資源的狀態。默認狀況下,在執行部署計劃後,Terraform 的狀態文件會存儲在本地,可是這樣每每就形成一些弊端:php
(1)不適用團隊之間協助,就比如在數據庫中對同一條數據進行操做時,就會引發異常html
(2)狀態文件中包含一些機密信息,會形成必定的機密泄露java
(3)若是不慎將本地的狀態文件刪除掉的話,已執行部署計劃的資源的管理將很難在經過 Terraform 進行管理python
因此,Terraform 是支持在遠端存儲狀態文件,也就是在 Azure Storage Account 中存儲遠端狀態文件,Terraform 狀態的存儲是由一個稱之爲Backend的組件決定的,local state使用的是local backend。而且其餘全部的Backend在使用以前都須要在模板中顯式定義並經過 terraform init 來實現加載和配置。mysql
--------------------Azure Terraform 系列--------------------linux
轉到Azure Portal 上,點擊 「+ Create a resource」,輸入 「Storage account「 進行搜索,而且點擊 」create「git
輸入如下參數:github
Resource group 選擇:」Web_Test_TF_RG「web
Storage account name:」cnbateterraformstorage「sql
Location:」(Asia Pacific) East Asia「
Performance:」Standard「
Account kind (帳戶類型)選擇:」BlobStorage「
Replication (複製)選擇:」Locally-redundant storage(LRS)「 (本地冗餘存儲(LRS))
點擊 」Review + create「 進行建立預校驗
校驗完成後,點擊 」Create「 進行建立操做
稍等片刻,等待建立完成後,點擊 」go to resource「 跳轉到資源能夠查看建立的資源。
選擇 「Blog service =》Containers」,點擊頁面上的 「+ Container」 添加存儲狀態文件的 Container
Name:"terraform-state"
Public access level:「Private(no anonymous access)」
點擊 「Create」 進行建立。
能夠看到剛剛建立容器
複製存儲帳戶的訪問密鑰,稍後會有用
回到 Azure Portal 首頁,點擊 」+ create a resource「,輸入」Key Vault「 進行搜索,點擊 」Create「 建立
輸入相關參數:
Resource group 選擇:」Web_Test_TF_RG「
Key vault name:」cnbate-terraform-kv「
Region:」East Asia「
Pricing tier:」Standard「
點擊 」Review + create「 ,建立預校驗。
預校驗完成後,點擊 」Create「 進行建立操做
建立完成後,能夠點擊 」Go to resource「 查看建立好的資源
選擇 「Settings=》Secrets」,點擊 「+ Generate/Import」 建立、或者導入機密信息
Upload options:「Manual」(手動)
Name:「terraform-stste-storage-key」
Value:複製粘貼剛剛的存儲帳戶訪問密鑰
建立成功,而且能夠查看到剛剛建立的機密信息
Terraform 須要配置後端,須要如下參數
(1)storage_account_name :Azure 存儲帳戶名稱
terraform init -backend-config="access_key=$(az keyvault secret show --name terraform-stste-storage-key --vault-name cnbate-terraform-kv --query value -o tsv)"
(2)container_name:容器名稱
(3)key:存儲狀態文件的名稱
(4)access_key:存儲帳戶訪問密鑰
你們須要注意的是,我這裏將 「access_key」 也就是存儲帳戶訪問密鑰存放在 Azure Key Vault 中了,想要獲取 「access_key」 就得經過 Azure Key Vault 獲取。
如下是 Terraform 後端配置
terraform { backend "azurerm" { storage_account_name = "cnbateterraformstorage" container_name = "terraform-state" key = "cnbate.terraform.stats" } }
3.1,初始化 Terraform 代碼
既然咱們沒有在 Terraform 後端配置代碼塊中添加 「access_key」 的信息,那麼咱們就得在初始化的時候對 」access_key「 信息賦值
terraform init -backend-config="access_key=$(az keyvault secret show --name terraform-stste-storage-key --vault-name cnbate-terraform-kv --query value -o tsv)"
而後,咱們能夠看到執行初始化命令以後的日誌輸出
同時會在存儲帳戶的容器中生成 Blob 塊
而且能夠看到當前blob 塊的詳細信息
LEASE STATUS:解鎖狀態
LEASE STATE:可用狀態
3.2,生成執行計劃
terraform plan
如下是執行後輸入的日誌信息
從中不難看到,在生成執行計劃以前,先獲取狀態鎖。(注意,生成執行計劃。不會將該執行計劃持久化到遠程狀態存儲)
PS D:\Core\Terraform\Azure\terraform_cnbate_traffic manager> terraform plan Acquiring state lock. This may take a few moments... Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. data.azurerm_resource_group.cnbate_resource_group: Refreshing state... ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # azurerm_app_service.cnbate_app_service01 will be created + resource "azurerm_app_service" "cnbate_app_service01" { + app_service_plan_id = (known after apply) + app_settings = { + "ASPNETCORE_ENVIRONMENT" = "Production" } + client_affinity_enabled = false + client_cert_enabled = false + custom_domain_verification_id = (known after apply) + default_site_hostname = (known after apply) + enabled = true + https_only = false + id = (known after apply) + location = "eastasia" + name = "CnBateBlogWeb01" + outbound_ip_address_list = (known after apply) + outbound_ip_addresses = (known after apply) + possible_outbound_ip_address_list = (known after apply) + possible_outbound_ip_addresses = (known after apply) + resource_group_name = "Web_Test_TF_RG" + site_credential = (known after apply) + auth_settings { + additional_login_params = (known after apply) + allowed_external_redirect_urls = (known after apply) + default_provider = (known after apply) + enabled = (known after apply) + issuer = (known after apply) + runtime_version = (known after apply) + token_refresh_extension_hours = (known after apply) + token_store_enabled = (known after apply) + unauthenticated_client_action = (known after apply) + active_directory { + allowed_audiences = (known after apply) + client_id = (known after apply) + client_secret = (sensitive value) } + facebook { + app_id = (known after apply) + app_secret = (sensitive value) + oauth_scopes = (known after apply) } + google { + client_id = (known after apply) + client_secret = (sensitive value) + oauth_scopes = (known after apply) } + microsoft { + client_id = (known after apply) + client_secret = (sensitive value) + oauth_scopes = (known after apply) } + twitter { + consumer_key = (known after apply) + consumer_secret = (sensitive value) } } + connection_string { + name = (known after apply) + type = (known after apply) + value = (sensitive value) } + identity { + identity_ids = (known after apply) + principal_id = (known after apply) + tenant_id = (known after apply) + type = (known after apply) } + logs { + detailed_error_messages_enabled = (known after apply) + failed_request_tracing_enabled = (known after apply) + application_logs { + file_system_level = (known after apply) + azure_blob_storage { + level = (known after apply) + retention_in_days = (known after apply) + sas_url = (sensitive value) } } + http_logs { + azure_blob_storage { + retention_in_days = (known after apply) + sas_url = (sensitive value) } + file_system { + retention_in_days = (known after apply) + retention_in_mb = (known after apply) } } } + site_config { + always_on = (known after apply) + app_command_line = (known after apply) + auto_swap_slot_name = (known after apply) + default_documents = (known after apply) + dotnet_framework_version = (known after apply) + ftps_state = (known after apply) + health_check_path = (known after apply) + http2_enabled = (known after apply) + ip_restriction = (known after apply) + java_container = (known after apply) + java_container_version = (known after apply) + java_version = (known after apply) + linux_fx_version = (known after apply) + local_mysql_enabled = (known after apply) + managed_pipeline_mode = (known after apply) + min_tls_version = (known after apply) + php_version = (known after apply) + python_version = (known after apply) + remote_debugging_enabled = (known after apply) + remote_debugging_version = (known after apply) + scm_ip_restriction = (known after apply) + scm_type = (known after apply) + scm_use_main_ip_restriction = (known after apply) + use_32_bit_worker_process = (known after apply) + websockets_enabled = (known after apply) + windows_fx_version = (known after apply) + cors { + allowed_origins = (known after apply) + support_credentials = (known after apply) } } + source_control { + branch = (known after apply) + manual_integration = (known after apply) + repo_url = (known after apply) + rollback_enabled = (known after apply) + use_mercurial = (known after apply) } + storage_account { + access_key = (sensitive value) + account_name = (known after apply) + mount_path = (known after apply) + name = (known after apply) + share_name = (known after apply) + type = (known after apply) } } # azurerm_app_service.cnbate_app_service02 will be created + resource "azurerm_app_service" "cnbate_app_service02" { + app_service_plan_id = (known after apply) + app_settings = { + "ASPNETCORE_ENVIRONMENT" = "Production" } + client_affinity_enabled = false + client_cert_enabled = false + custom_domain_verification_id = (known after apply) + default_site_hostname = (known after apply) + enabled = true + https_only = false + id = (known after apply) + location = "southeastasia" + name = "CnBateBlogWeb02" + outbound_ip_address_list = (known after apply) + outbound_ip_addresses = (known after apply) + possible_outbound_ip_address_list = (known after apply) + possible_outbound_ip_addresses = (known after apply) + resource_group_name = "Web_Test_TF_RG" + site_credential = (known after apply) + auth_settings { + additional_login_params = (known after apply) + allowed_external_redirect_urls = (known after apply) + default_provider = (known after apply) + enabled = (known after apply) + issuer = (known after apply) + runtime_version = (known after apply) + token_refresh_extension_hours = (known after apply) + token_store_enabled = (known after apply) + unauthenticated_client_action = (known after apply) + active_directory { + allowed_audiences = (known after apply) + client_id = (known after apply) + client_secret = (sensitive value) } + facebook { + app_id = (known after apply) + app_secret = (sensitive value) + oauth_scopes = (known after apply) } + google { + client_id = (known after apply) + client_secret = (sensitive value) + oauth_scopes = (known after apply) } + microsoft { + client_id = (known after apply) + client_secret = (sensitive value) + oauth_scopes = (known after apply) } + twitter { + consumer_key = (known after apply) + consumer_secret = (sensitive value) } } + connection_string { + name = (known after apply) + type = (known after apply) + value = (sensitive value) } + identity { + identity_ids = (known after apply) + principal_id = (known after apply) + tenant_id = (known after apply) + type = (known after apply) } + logs { + detailed_error_messages_enabled = (known after apply) + failed_request_tracing_enabled = (known after apply) + application_logs { + file_system_level = (known after apply) + azure_blob_storage { + level = (known after apply) + retention_in_days = (known after apply) + sas_url = (sensitive value) } } + http_logs { + azure_blob_storage { + retention_in_days = (known after apply) + sas_url = (sensitive value) } + file_system { + retention_in_days = (known after apply) + retention_in_mb = (known after apply) } } } + site_config { + always_on = (known after apply) + app_command_line = (known after apply) + auto_swap_slot_name = (known after apply) + default_documents = (known after apply) + dotnet_framework_version = (known after apply) + ftps_state = (known after apply) + health_check_path = (known after apply) + http2_enabled = (known after apply) + ip_restriction = (known after apply) + java_container = (known after apply) + java_container_version = (known after apply) + java_version = (known after apply) + linux_fx_version = (known after apply) + local_mysql_enabled = (known after apply) + managed_pipeline_mode = (known after apply) + min_tls_version = (known after apply) + php_version = (known after apply) + python_version = (known after apply) + remote_debugging_enabled = (known after apply) + remote_debugging_version = (known after apply) + scm_ip_restriction = (known after apply) + scm_type = (known after apply) + scm_use_main_ip_restriction = (known after apply) + use_32_bit_worker_process = (known after apply) + websockets_enabled = (known after apply) + windows_fx_version = (known after apply) + cors { + allowed_origins = (known after apply) + support_credentials = (known after apply) } } + source_control { + branch = (known after apply) + manual_integration = (known after apply) + repo_url = (known after apply) + rollback_enabled = (known after apply) + use_mercurial = (known after apply) } + storage_account { + access_key = (sensitive value) + account_name = (known after apply) + mount_path = (known after apply) + name = (known after apply) + share_name = (known after apply) + type = (known after apply) } } # azurerm_app_service_plan.cnbate_app_service_plan01 will be created + resource "azurerm_app_service_plan" "cnbate_app_service_plan01" { + id = (known after apply) + kind = "Windows" + location = "eastasia" + maximum_elastic_worker_count = (known after apply) + maximum_number_of_workers = (known after apply) + name = "cnbate_appserviceplan01" + resource_group_name = "Web_Test_TF_RG" + sku { + capacity = (known after apply) + size = "S1" + tier = "Standard" } } # azurerm_app_service_plan.cnbate_app_service_plan02 will be created + resource "azurerm_app_service_plan" "cnbate_app_service_plan02" { + id = (known after apply) + kind = "Windows" + location = "southeastasia" + maximum_elastic_worker_count = (known after apply) + maximum_number_of_workers = (known after apply) + name = "cnbate_appserviceplan02" + resource_group_name = "Web_Test_TF_RG" + sku { + capacity = (known after apply) + size = "S1" + tier = "Standard" } } # azurerm_traffic_manager_endpoint.cnbate_traffic_manager_endpoint01 will be created + resource "azurerm_traffic_manager_endpoint" "cnbate_traffic_manager_endpoint01" { + endpoint_location = (known after apply) + endpoint_monitor_status = (known after apply) + endpoint_status = (known after apply) + geo_mappings = [ + "CN", ] + id = (known after apply) + name = "cnbateblogweb_webapp01_performance" + priority = (known after apply) + profile_name = "cnbateblogweb" + resource_group_name = "Web_Test_TF_RG" + target = (known after apply) + target_resource_id = (known after apply) + type = "azureEndpoints" + weight = (known after apply) } # azurerm_traffic_manager_endpoint.cnbate_traffic_manager_endpoint02 will be created + resource "azurerm_traffic_manager_endpoint" "cnbate_traffic_manager_endpoint02" { + endpoint_location = (known after apply) + endpoint_monitor_status = (known after apply) + endpoint_status = (known after apply) + geo_mappings = [ + "SG", ] + id = (known after apply) + name = "cnbateblogweb_webapp02_performance" + priority = (known after apply) + profile_name = "cnbateblogweb" + resource_group_name = "Web_Test_TF_RG" + target = (known after apply) + target_resource_id = (known after apply) + type = "azureEndpoints" + weight = (known after apply) } # azurerm_traffic_manager_profile.cnbate_traffic_manager_profile will be created + resource "azurerm_traffic_manager_profile" "cnbate_traffic_manager_profile" { + fqdn = (known after apply) + id = (known after apply) + name = "cnbateblogweb" + profile_status = (known after apply) + resource_group_name = "Web_Test_TF_RG" + tags = { + "Environment" = "Production" } + traffic_routing_method = "Geographic" + dns_config { + relative_name = "cnbateblogweb" + ttl = 60 } + monitor_config { + interval_in_seconds = 30 + path = "/" + port = 80 + protocol = "http" + timeout_in_seconds = 10 + tolerated_number_of_failures = 3 } } Plan: 7 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run. PS D:\Core\Terraform\Azure\terraform_cnbate_traffic manager>
3.3,執行部署計劃
terraform apply
如下是正在執行部署計劃輸入日誌
一樣,也是先獲取狀態鎖
PS D:\Core\Terraform\Azure\terraform_cnbate_traffic manager> terraform plan Acquiring state lock. This may take a few moments... Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. data.azurerm_resource_group.cnbate_resource_group: Refreshing state...
在執行的過程當中,咱們再次登陸Azure Portal 中,查看存儲帳容器中的 Blob 塊的狀態
LEASE STATUS:已鎖定
LEASE STATE:已租用(其實能夠理解爲 「不可用」)
等待部署計劃執行完畢以後,Blob 塊的狀態又恢復到 「已解鎖,可用」
同時,點擊圖中的 「Edit」 能夠看到由 terraform 管理的各自資源狀態信息所有寫到了當前 Blob 塊中
ok,今天的內容就先到此。重要提醒:你們作完測試後,別忘記執行 terraform destroy (銷燬部署計劃)
*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。φ(゜▽゜*)♪是✌✌✌✌✌
將狀態文件進行遠端存到Azure Storage Account 中,Blob 中存儲的數據會在保存前進行加密處理,而且一旦配置遠端存儲模式後,狀態文件永遠不會存儲在本地,這樣更加方面團隊之間的協做。而且遠端存儲帶來的好處是實現了與資源定義模板管理的解耦,可讓 Terraform 狀態脫離本地磁盤而存儲,提高了資源狀態的安全性。
參考資料:Terraform 官方,azurerm 文檔
Terraform_Cnbate_Traffic_Manager github:https://github.com/yunqian44/Terraform_Cnbate_Traffic_Manager
做者:Allen
版權:轉載請在文章明顯位置註明做者及出處。如發現錯誤,歡迎批評指正。