Azure Terraform(四)狀態文件存儲

一,引言

  咱們都知道在執行部署計劃以後,當前目錄中就產生了名叫 「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

1,Azure Terraform(一)入門簡介

2,Azure Terraform(二)語法詳解

3,Azure Terraform(三)部署 Web 應用程序

4,Azure Terraform(四)狀態文件存儲

二,正文

1,建立狀態文件存儲帳戶

轉到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」 進行建立。

能夠看到剛剛建立容器

複製存儲帳戶的訪問密鑰,稍後會有用

2,建立 Azure Key Vault(密鑰保管庫)

回到 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:複製粘貼剛剛的存儲帳戶訪問密鑰

建立成功,而且能夠查看到剛剛建立的機密信息

3,配置 Terraform 後端,而且測試遠程 tf 狀態

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 

版權:轉載請在文章明顯位置註明做者及出處。如發現錯誤,歡迎批評指正。

相關文章
相關標籤/搜索