Azure Terraform(四)状态文件存储
一,引言
我们都知道在执行部署计划之后,当前目录中就产生了名叫 “” 的 Terraform 的状态文件,该文件中记录了已部署资源的状态。默认情况下,在执行部署计划后,Terraform 的状态文件会存储在本地,但是这样往往就造成一些弊端:
(1)不适用团队之间协助,就好比在数据库中对同一条数据进行操作时,就会引起异常
(2)状态文件中包含一些机密信息,会造成一定的机密泄露
(3)如果不慎将本地的状态文件删除掉的话,已执行部署计划的资源的管理将很难在通过 Terraform 进行管理
所以,Terraform 是支持在远端存储状态文件,也就是在 Azure Storage Account 中存储远端状态文件,Terraform 状态的存储是由一个称之为Backend的组件决定的,local state使用的是local backend。并且其他所有的Backend在使用之前都需要在模板中显式定义并通过 terraform init 来实现加载和配置。
二,正文
1,创建状态文件存储账户
转到Azure Portal 上,点击 “+ Create a resource”,输入 “Storage account“ 进行搜索,并且点击 ”create“
输入以下参数:
Resource group 选择:”Web_Test_TF_RG“
Storage account name:”cnbateterraformstorage“
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
版权:转载请在文章明显位置注明作者及出处。如发现错误,欢迎批评指正。
Azure Terraform(四)状态文件存储的更多相关文章
- Azure Terraform(七)利用Azure DevOps 实现自动化部署基础资源(补充)
一,引言 之前一篇文章有讲解到利用 利用Azure DevOps 实现自动化部署基础资源,当时 TF 代码没有针对 Azure 各个资源的封装,所有的资源代码全部写在一个 main.tf 文件中.然后 ...
- Azure Terraform(五)利用Azure DevOps 实现自动化部署基础资源
一,引言 上一篇我们结合学习 Azure Traffic Manger 的内容,做了一个负载均衡的基础设施架构.通过 Terraform 部署执行计划,将整个 Azure Traffic Manage ...
- Azure Terraform(六)Common Module
一,引言 之前我们在使用 Terraform 构筑一下 Azure 云资源的时候,直接将所以需要创建的资源全面写在 main.tf 这个文件中,这样写主要是为了演示使用,但是在实际的 Terrafor ...
- Azure Terraform(八)利用Azure DevOps 实现Infra资源和.NET CORE Web 应用程序的持续集成、持续部署
一,引言 上一篇讲解到利用 Azure DevOps 将整个 Azure Web App,Azure Traffic Manager profile,Azure Storage Account,Azu ...
- Azure Terraform(九)利用 Azure DevOps Pipeline 的审批来控制流程发布
一,引言 Azure Pipeline 管道是一个自动化过程:但是往往我们由于某种原因,需要在多个阶段之前获得批准之后再继续下一步流程,所以我们可以向Azure Pipeline 管道添加审批!批准流 ...
- Azure Terraform(十)利用 Azure DevOps 的条件语句选择发布环境
一,引言 之前我讲过的所有的案例中,都是将整个Azure Resource 部署到同一个订阅下,没有做到灵活的在 Azure Pipeline 在运行前选择需要部署的环境.在实际的项目开发中,我们也会 ...
- Azure Terraform(十一)Azure DevOps Pipeline 内的动态临时变量的使用
思路浅析 在我们分析的 Azure Terraform 系列文中有介绍到关于 Terraform 的状态文件远程存储的问题,我们在 Azure DevOps Pipeline 的 Task Job ...
- Azure Terraform(二)语法详解
一,引言 上篇文章开始,我们简单介绍了以下通过基础设施管理工具----- Terraform,通过它来统一管理复杂的云基础设施资源.作为入门演示,使用Terraform 部署Azure 资源组的方式直 ...
- [ Android 五种数据存储方式之二 ] —— 文件存储数据
关于文件存储,Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的. 文件可用来存放大量数据,如文本.图片.音 ...
随机推荐
- Codeforces Edu Round 64 A-D
A. Inscribed Figures 分类讨论打表即可. PS:这道题翻译有歧义. 这样稍微翻转一下,就可以是\(7\)个交点呀...(大概是我没看英文题干导致的惨案) #include < ...
- git使用-merge request开发操作步骤
0. 如果当前不在develop分支,则切换到develop分支 git checkout develop 1. 获取develop分支最新代码 git pull 注意:这一步正常来说应该是一个Fas ...
- uni-app中组件的使用
组件基本知识点: uniapp中:每个页面可以理解为一个单页面组件,这些单页面组件注册在pages.json里,在组件关系中可以看作父组件. 自定义可复用的组件,其结构与单页面组件类似,通常在需要的页 ...
- 前端js实现九宫格模式抽奖(多宫格抽奖)
介绍: 前端九宫格是一种常见的抽奖方式,js实现如下,掌握其原理,不论多少宫格,都可以轻松应对.(代码可复制直接运行看效果). 该案例以四宫格入门,可扩展多宫格,奖品模块的布局可自由设置. <! ...
- JavaSE基础面试题
1. Java语言有哪些特点(1)简单易学.有丰富的类库(2)面向对象(Java最重要的特性,让程序耦合度更低,内聚性更高)(3)与平台无关性(JVM是Java跨平台使用的根本)(4)可靠安全(5)支 ...
- Linux相关介绍和安装
目录 前言 第一章 linux介绍 1.1 linux简介 第二章 Linux起源 2.1 Unix的历史 2.2 Unix操作系统的革命 2.3 Linux系统的诞生 2.4 Linux系统的发展史 ...
- 推荐系统实践 0x0f AutoRec
从这一篇开始,我们开始学习深度学习推荐模型,与传统的机器学习相比,深度学习模型的表达能力更强,并且更能够挖掘出数据中潜藏的模式.另外.深度学习模型结构也非常灵活,能够根据业务场景和数据结构进行调整.还 ...
- .net core WebAPI性能监控-MiniProfiler与Swagger集成
------------恢复内容开始------------ 安装Nuget Install-Package MiniProfiler.AspNetCore.Mvc Install-Package M ...
- 用Python实现童年的回忆:俄罗斯方块!别说还挺好玩
在那个电子产品比较匮乏的年代,小游戏机
- webform中配置服务器控件的样式
前台 Style <asp:Label ID="Label1" runat="server" Text="Label" Style=& ...