《Terraform 101 从入门到实践》 第四章 States状态管理
《Terraform 101 从入门到实践》这本小册在南瓜慢说官方网站和GitHub两个地方同步更新,书中的示例代码也是放在GitHub上,方便大家参考查看。
军书十二卷,卷卷有爷名。
为什么需要状态管理
Terraform的主要作用是管理云平台上的资源,通过声明式的HCL配置来映射资源,如果云平台上没有资源则需要创建,如果有则不用。那Terraform要实现这个功能有多种方式。
一种是每次执行apply命令时都调用API接口检查一下远程的云资源是否与配置文件一致,如果没有则创建,如果有但不同则需要修改,如果有且相同则不用变更。这种机制能保证云平台的资源与HCL配置是一致的。缺点也是非常明显的,每次都需要调用API去检查远程资源,效率很低,特别是当资源特别多的场景。
另一种方式是每次变更资源的时候,都会创建一个映射文件,它保存云平台资源的状态。这样每次执行apply
命令时,只需要检查HCL配置与映射文件的差异即可。
Terraform选择的是第二种方式,通过映射文件来保存资源状态,在Terraform的世界里叫状态文件。Terraform这样做是基于以下考虑:
- 云平台真实状态的映射,解析状态文件即可以知道真实情况。
- 元数据存储,如资源之间的依赖关系,需要通过依赖关系来知道创建或销毁顺序。
- 提升性能,特别是在大规模云平台上,多次调用API去查询资源状态是很费时的。
- 同步状态,通过远程状态文件来同步状态,这也是Terraform最佳的实践。
讲到这里,已经回答了之前在第一章留下的思考题:
如果再次执行apply会不会再次创建一个文件呢?还是创建失败,因为文件已存在?为什么?
答案:不会创建,因为通过状态文件记录了变更,Terraform判断不再需要创建了。
状态管理的示例
为了更多注意力放在状态管理上,我们还是使用最简单的例子local_file
,具体代码如下:
resource "local_file" "terraform-introduction" {content = "https://www.pkslow.com"filename = "${path.root}/terraform-guides-by-pkslow.txt"
}
我们以实际操作及现象来讲解状态文件的作用和工作原理:
操作 | 现象及说明 |
---|---|
terraform apply | 生成资源:第一次生成 |
terraform apply | 没有变化:状态文件生成,不需要再创建 |
terraform destroy | 删除资源:根据状态文件的内容删除 |
terraform apply | 生成资源:状态显示没有资源,再次生成 |
删除状态文件 | 没有变化 |
terraform apply | 生成资源:没有状态文件,直接生成资源和状态文件(插件做了容错处理,已存在也会新生成覆盖) |
删除状态文件 | 没有变化 |
terraform destroy | 无法删除资源,没有资源存在的状态 |
我们一直在讲状态文件,我们先来看一下它的真面目。首先它的默认文件名是terraform.tfstate
,默认会放在当前目录下。它是以json
格式存储的信息,示例中的内容如下:
{"version": 4,"terraform_version": "1.0.11","serial": 1,"lineage": "acb408bb-2a95-65fd-02e6-c23487f7a3f6","outputs": {},"resources": [{"mode": "managed","type": "local_file","name": "test-file","provider": "provider[\"registry.terraform.io/hashicorp/local\"]","instances": [{"schema_version": 0,"attributes": {"content": "https://www.pkslow.com","content_base64": null,"directory_permission": "0777","file_permission": "0777","filename": "./terraform-guides-by-pkslow.txt","id": "6db7ad1bbf57df0c859cd5fc62ff5408515b5fc1","sensitive_content": null,"source": null},"sensitive_attributes": [],"private": "bnVsbA=="}]}]
}
可以看到它记录了Terraform的版本信息,还有资源的详细信息:包括类型、名字、插件、属性等。有这些信息便可直接从状态文件里解析出具体的资源。
状态管理命令
可以通过terraform state
做一些状态管理:
显示状态列表:
$ terraform state list
local_file.test-file
查看具体资源的状态信息:
$ terraform state show local_file.test-file
# local_file.test-file:
resource "local_file" "test-file" {content = "https://www.pkslow.com"directory_permission = "0777"file_permission = "0777"filename = "./terraform-guides-by-pkslow.txt"id = "6db7ad1bbf57df0c859cd5fc62ff5408515b5fc1"
}
显示当前状态信息:
$ terraform state pull
重命名:
$ terraform state mv local_file.test-file local_file.pkslow-file
Move "local_file.test-file" to "local_file.pkslow-file"
Successfully moved 1 object(s).$ terraform state list
local_file.pkslow-file
要注意这里只是修改状态文件的名字,代码里的HCL并不会修改。
删除状态里的资源:
$ terraform state rm local_file.pkslow-file
Removed local_file.pkslow-file
Successfully removed 1 resource instance(s).
远程状态
状态文件默认是在本地目录上的terraform.tfstate
文件,在团队使用中,每个人的电脑环境独立的,那么需要保证每个人当前的状态文件都是最新且与现实资源真实对应,简直是天方夜谭。而状态不一致所带的灾难也是极其可怕的。所以,状态文件最好是要存储在一个独立的大家可共同访问的位置。对于状态的管理的配置,Terraform称之为Backends
。
Backend
是两种模式,分别是local
和remote
。local
模式很好理解,就是使用本地路径来存储状态文件。配置示例如下:
terraform {backend "local" {path = "pkslow.tfstate"}
}
通过这样配置后,不再使用默认的terraform.tfstate
文件,而是使用自定义的文件名pkslow.tfstate
。
对于remote
模式,则有多种配置方式,Terraform支持的有:
- s3
- gcs
- oss
- etcd
- pg
- http
- kubernetes
等,能满足主流云平台的需求。每一个配置可以参考官网,在本地我采用数据库postgresql的方式,让大家都能快速实验。
我通过Docker的方式启动PostgreSQL,命令如下:
$ docker run -itd \--name terraform-postgres \-e POSTGRES_DB=terraform \-e POSTGRES_USER=pkslow \-e POSTGRES_PASSWORD=pkslow \-p 5432:5432 \postgres:13
在terraform
块中配置backend
,这里指定数据库连接信息即可,更多参数请参考:https://www.terraform.io/language/settings/backends/pg
terraform {backend "pg" {conn_str = "postgres://pkslow:pkslow@localhost:5432/terraform?sslmode=disable"}
}
当然,把敏感信息直接放在代码中并不合适,可以直接在命令行中传入参数:
terraform init -backend-config="conn_str=postgres://pkslow:pkslow@localhost:5432/terraform?sslmode=disable"
执行init和apply之后,连接数据库查看,会创建一个叫terraform_remote_state
的Schema,在该Schema下有一张states表来存储对应的状态信息,如下:
表中字段name是namespace,而data是具体的状态信息,如下:
{"version": 4,"terraform_version": "1.0.11","serial": 0,"lineage": "de390d13-d0e0-44dc-8738-d95b6d8f1868","outputs": {},"resources": [{"mode": "managed","type": "local_file","name": "test-file","provider": "provider[\"registry.terraform.io/hashicorp/local\"]","instances": [{"schema_version": 0,"attributes": {"content": "https://www.pkslow.com","content_base64": null,"directory_permission": "0777","file_permission": "0777","filename": "./terraform-guides-by-pkslow.txt","id": "6db7ad1bbf57df0c859cd5fc62ff5408515b5fc1","sensitive_content": null,"source": null},"sensitive_attributes": [],"private": "bnVsbA=="}]}]
}
Workspace 工作区
如果我们用Terraform代码生成了dev环境,但现在需要uat环境,该如何处理呢?
首先,不同环境的变量一般是不一样的,我们需要定义各种的变量文件如dev.tfvars
、uat.tfvars
和prod.tfvars
等。但只有各自变量是不够的,因为还有状态。状态也必须要隔离,而Workspace
就是Terraform用来隔离状态的方式。默认的工作区为default
,如果没有指定,则表示工作于default
工作区中。而当指定了工作区,状态文件就会与工作区绑定。
创建一个工作区并切换:
$ terraform workspace new pkslow
切换到已存在的工作区:
$ terraform workspace select pkslow
而当我们处于某个工作区时,是可以获取工作区的名字的,引用为:${terraform.workspace}
,示例如下:
resource "aws_instance" "example" {count = "${terraform.workspace == "default" ? 5 : 1}"# ... other arguments
}
之前讲过默认的状态文件名为terraform.tfstate
;而在多工作区的情况下(只要你创建了一个非默认工作区),状态文件就会存在terraform.tfstate.d
目录下。而在远程状态的情况下,也会有一个映射,Key为工作区名,Value一般是状态内容。
敏感数据
本地状态文件都是明文存储状态信息的,所以要保护好自己的状态文件。对于远程状态文件,有些存储方案是支持加密的,会对敏感数据(sensitive
)进行加密。
状态锁
本地状态文件下不需要状态锁,因为只有一个人在变更。而远程状态的情况下,就可能出现竞争了。比如一个人在apply,而另一个人在destroy,那就乱了。而状态锁可以确保远程状态文件只能被一个人使用。但不是所有远程状态的方式都支持锁的,一般常用的都会支持,如GCS、S3等。
所以,每当我们在执行变更时,Terraform总会先尝试去拿锁,如果拿锁失败,就该命令失败。可以强制解锁,但要非常小心,一般只建议在自己明确知道安全的时候才使用,比如死锁了。
共享状态-数据源
既然远程状态文件是可以共享的,那状态信息也是可以共享的。这样会带来的一个好处是,即使两个根模块,也是可以共享信息的。比如我们在根模块A创建了一个数据库,而根模块B需要用到数据库的信息如IP,这样通过远程状态文件就可以共享给根模块B了。
注意这里我强调的是根模块,因为如果A和B在同一个根模块下,那就不需要通过远程状态的方式来共享状态了。
远程状态的示例:
data "terraform_remote_state" "vpc" {backend = "remote"config = {organization = "hashicorp"workspaces = {name = "vpc-prod"}}
}resource "aws_instance" "foo" {# ...subnet_id = data.terraform_remote_state.vpc.outputs.subnet_id
}
本地状态的示例:
data "terraform_remote_state" "vpc" {backend = "local"config = {path = "..."}
}resource "aws_instance" "foo" {# ...subnet_id = data.terraform_remote_state.vpc.outputs.subnet_id
}
要注意的是,只有根模块的输出变量才能被共享,子模块是不能被获取的。
相关文章:

《Terraform 101 从入门到实践》 第四章 States状态管理
《Terraform 101 从入门到实践》这本小册在南瓜慢说官方网站和GitHub两个地方同步更新,书中的示例代码也是放在GitHub上,方便大家参考查看。 军书十二卷,卷卷有爷名。 为什么需要状态管理 Terraform的主要作用是管理云平台上的资源ÿ…...

数据结构之二叉树
🎈一.二叉树相关概念 1.树 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合,树结构通常用来存储逻辑关系为 "一对多" 的数据。例如: 关于树的几个重要概念&…...

上海亚商投顾:三大指数集体调整 消费板块逆市活跃
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。市场情绪三大指数今日集体调整,沪指全天弱势震荡,创业板指盘中跌超1%。旅游、食品、乳业等大消费板块…...

【2023unity游戏制作-mango的冒险】-开始画面API制作
👨💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:游戏制作 ⭐mango的冒险-开始画面制作⭐ 文章目录⭐mango的冒险-开始画面制作⭐👨&…...

【微服务】Nacos配置管理
🚩本文已收录至专栏:微服务探索之旅 👍希望您能有所收获 Nacos除了可以做配置管理,同样可以当作注册中心来使用。 了解注册中心用法点击跳转👉【微服务】Nacos注册中心 一.引入 当微服务部署的实例越来越多࿰…...

【C++】类与对象理解和学习(上)
专栏放在【C知识总结】,会持续更新,期待支持🌹类是什么?类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它(实例化后才…...

Pyqt5小案例,界面与逻辑分离的小计算器程序
直接看下最终效果: 使用技术总结 使用Designer设计界面 使用pyuic5命令导出到python文件 新建逻辑处理文件,继承pyuic5导出的文件的类,在里面编写信号与槽的处理逻辑 使用Designer设计界面 要使用Designer,安装一个Python库即…...

leaflet加载KML文件,显示图形(方法2)
第049个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载KML文件,将图形显示在地图上。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果OpenStreetMap无法加载,请加载其他来练习 文章目录 示例效果配置方式示例源代码(共66…...

Mysql 部署 MGR 集群
0. 参考文章 官方文档: MySQL :: MySQL 8.0 Reference Manual :: 18.2 Getting Started 博客: MGR 单主模式部署教程(基于 MySQL 8.0.28) - 墨天轮 (modb.pro) mysql MGR单主模式的搭建 - 墨天轮 (modb.pro) MySQL 5.7 基于…...

迁移至其他美国主机商时需要考虑的因素
网站的可访问性是关系业务的关键因素之一。一个稳定、快速且优化良好的主机上的网站更有可能享受不间断的流量,并在谷歌的SERP中获得更好的排名。因此,在构建企业网站时,选择合适的主机商相当重要。不过就以美国主机为例,由于每个…...

【数据结构】第二章 线性表
文章目录第二章 知识体系2.1 线性表的定义和基本操作2.1.1 线性表的定义2.1.2 线性表的基本操作2.2 线性表的顺序表示2.2.1 顺序表的定义2.2.2 顺序表的基本操作的实现2.3 线性表的链式表示2.3.1 单链表的定义2.3.2 单链表的基本操作实现2.3.3 双链表2.3.4 循环链表2.3.5 静态链…...

RESTful API 为何成为顶流 API 架构风格?
作者孙毅,API7.ai 技术工程师,Apache APISIX Committer 万物互联的世界充满着各式各样的 API ,如何统筹规范 API 至关重要。RESTful API 是目前世界上最流行的 API 架构风格之一,它可以帮助你实现客户端与服务端关注点分离&#x…...

Python基础知识点汇总(列表)
列表的含义 列表由一系列按特定顺序排列的元素组成,是Python中内置的可变序列。 **注:**列表的所有元素放在中括号[]中,相邻的两个元素用逗号分隔; 可将整数、实数、字符串、列表、元组等任何类型的内容放到列表中,且同一列表的元素类型可以不同。 列表的创建和删除 1.…...

新的一年软件测试行业的趋势能够更好?
如果说,2022年对于全世界来说,都是一场极大的挑战的话;那么,2023年绝对是机遇多多的一年。众所周知,随着疫情在全球范围内逐步得到控制,无论是国际还是国内的环境,都会呈现逐步回升的趋势&#…...

Threejs中的Shadow Mapping(阴影贴图)
简而言之,步骤如下: 1.从灯光位置视点(阴影相机)创建深度图。 2.从相机的位置角度进行屏幕渲染,在每个像素点,比较由阴影相机的MVP矩阵计算的深度值和深度图的值的大小,如果深度图值小的话&…...

本质安全设备标准(IEC60079-11)的理解(四)
本质安全设备标准(IEC60079-11)的理解(四) 对于标准中“Separation”的理解 IEC60079-11使用了较长的篇幅来说明设计中需要考虑到的各种间距, 这也从一定程度上说明了间距比较重要,在设计中是需要认真考虑…...

(record)QEMU安装最小linux系统——TinyCore(命令行版)
文章目录QEMU安装最小linux系统——TinyCore参考QEMU使用qemu创建tinycore虚拟机再次启动文件保存QEMU安装最小linux系统——TinyCore 简单记录安装过程和记录点 参考 [原创] qemu 与 Tiny Core tinycore的探索 QEMU qemu不多介绍,这里是在WSL2上安装的linux版…...

C++中的cast类型转换
reinterpret_cast用法:reinpreter_cast<type-id> (expression)type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针。这个操作符能够在非相关的类型之间转换。操作结果…...

西瓜数据集读取的详细解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...

Mac开发环境配置
一、mac 安装homebrew 1. 必要性 homebrew可以通过bash命令快速安装配置开发环境,并且在大多数情况下可以实现环境的自动配置。(一键安装配置) 2. 收益 节省开发环境工具配置时间,提高人效。 3. 安装步骤 打开mac终端…...

概率论面试题1:玫瑰花
概率论面试题 1. 一个活动,n个女生手里拿着长短不一的玫瑰花,无序的排成一排,一个男生从头走到尾,试图拿更长的玫瑰花,一旦拿了一朵就不能再拿其他的,错过了就不能回头,问最好的策略࿱…...

【DGL】图分类
目录概述数据集定义Data LoaderDGL中的batched graph定义模型训练参考概述 除了节点级别的问题——节点分类、边级别的问题——链接预测之外,还有整个图级别的问题——图分类。经过聚合、传递消息得到节点和边的新的表征后,映射得到整个图的表征。 数据…...

时间复杂度的计算(2023-02-10)
时间复杂度的计算 时间复杂度的计算分为三大类:一层循环、二层循环和多层循环。 一层循环 1.找出循环趟数t及每轮循环i的变化值 2.确立循环停止的条件 3.得出t与i之间的关系 4.联立两式,得出结果 eg: void fun(int n) {int i0;while (i*i*i<n)i;…...

测试开发之Django实战示例 第六章 追踪用户行为
第六章 追踪用户行为在之前的章节里完成了小书签将外站图片保存至本站的功能,并且实现了通过jQuery发送AJAX请求,让用户可以对图片进行喜欢/不喜欢操作。这一章将学习如何创建一个用户关注系统和创建用户行为流数据,还将学习Django的信号框架…...

红米9a手动root方法
简介 已知红米6A/6/9/9A/9C/10A机器都可以快速解锁BL,无任何变砖风险 并且秒解锁BL后和官方解锁一样,无任何其他不良影响。推荐大家使用官网解锁,需要等待7天。 BootLoader BootLoader是在操作系统内核运行之前运行的一段小程序。其实…...

Open3D 点云最小二乘法拟合平面(剔除噪声,Python版本)
除了诱惑之外,我可以抵抗任何事物。 ----王尔德 文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这个算法的思路很简单,就是通过剔除一些异常点来拟合更为合适的平面,具体过程如下所示: 1、首先使用最小二乘法拟合一个平面系数的初值。 2、计算所有有效点到拟合…...

【SpringBoot】简述springboot项目启动数据加载内存中的三种方法
一、前言一般来说,SpringBoot工程环境配置放在properties文件中,启动的时候将工程中的properties/yaml文件的配置项加载到内存中。但这种方式改配置项的时候,需要重新编译部署,考虑到这种因素,今天介绍将配置项存到数据…...

【一文速通】各种机器学习算法的特点及应用场景
近邻 (Nearest Neighbor)KNN算法的核心思想是,如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定…...

多传感器融合定位十四-基于图优化的定位方法
多传感器融合定位十四-基于图优化的定位方法1. 基于图优化的定位简介1.1 核心思路1.2 定位流程2. 边缘化原理及应用2.1 边缘化原理2.2 从滤波角度理解边缘化3. 基于kitti的实现原理3.1 基于地图定位的滑动窗口模型3.2 边缘化过程4. lio-mapping 介绍4.1 核心思想4.2 具体流程4.…...

PHP基于TCPDF第三方类生成PDF文件
最近在研发招聘的系统 遇到了这个问题 转换pdf 折腾了很久 分享一下PHP基于TCPDF第三方类生成PDF文件最近遇到一个需求,需要根据数据库的字段生成表格式的PDF文件并发送邮箱第一步、我们先去官网上面去下载tcpdf的类:http://www.tcpdf.org/或者是从githu…...