<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Infra on 维克的博客</title><link>https://blogs.wuvikr.top/tags/infra/</link><description>Recent content in Infra on 维克的博客</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 04 Sep 2026 16:08:53 +0800</lastBuildDate><atom:link href="https://blogs.wuvikr.top/tags/infra/index.xml" rel="self" type="application/rss+xml"/><item><title>Terraform 状态文件管理</title><link>https://blogs.wuvikr.top/posts/terraform%E7%8A%B6%E6%80%81%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/</link><pubDate>Fri, 04 Sep 2026 16:08:53 +0800</pubDate><guid>https://blogs.wuvikr.top/posts/terraform%E7%8A%B6%E6%80%81%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/</guid><description>&lt;h1 id="1-为什么要把-state-搬到云上">1. 为什么要把 State 搬到「云上」&lt;/h1>
&lt;p>State 文件是 Terraform 的「账本」：它记录云上到底有哪些资源、各自的属性。本地存放 State 有三个硬伤：&lt;/p>
&lt;ul>
&lt;li>绑定机器：State 在 A 电脑上，B 电脑 apply 就会&amp;quot;失忆&amp;quot;，容易把资源重建一遍。&lt;/li>
&lt;li>无法协作：两个人同时改同一个环境，互相覆盖，状态文件乱套。&lt;/li>
&lt;li>安全隐患：本地文件易丢，而且里面可能含有明文密码等敏感信息，因此也不建议上传到 gitlab 等代码托管平台。&lt;/li>
&lt;/ul>
&lt;p>解决办法就是 Terraform 的 &lt;strong>Backend 机制&lt;/strong>：&lt;strong>用阿里云 OSS 存 State（集中、加密、可回滚），用 Tablestore 提供加锁（防止多人并发操作冲突）&lt;/strong>。&lt;/p>
&lt;h1 id="2-工作原理">2. 工作原理&lt;/h1>
&lt;p>每次执行 Terraform 命令，OSS Backend 都会走「加锁 → 干活 → 放锁」三步：&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-mermaid" data-lang="mermaid">flowchart LR
A[terraform apply] --&amp;gt; B{从 Tablestore 拿 LockID}
B -- 已存在 --&amp;gt; C[报错：有人在操作]
B -- 不存在 --&amp;gt; D[生成并存入 LockID]
D --&amp;gt; E[读写 OSS 里的 State 文件]
E --&amp;gt; F[释放 LockID]
&lt;/code>&lt;/pre>&lt;ul>
&lt;li>&lt;strong>有锁&lt;/strong> → 说明有人正在操作，或上次操作异常退出，直接报错&lt;/li>
&lt;li>&lt;strong>无锁&lt;/strong> → 自动生成 LockID 存入 Tablestore，操作完成后更新 OSS 中的 State，再释放锁&lt;/li>
&lt;/ul>
&lt;h1 id="3-第一步创建存储--锁资源">3. 第一步：创建「存储 + 锁」资源&lt;/h1>
&lt;p>在正式使用前，要先准备一个 OSS Bucket 和一个 Tablestore 实例/表。它们本身也是云资源，所以也可以用 Terraform 自己建。&lt;/p></description></item><item><title>Terraform 云上存量资源导入</title><link>https://blogs.wuvikr.top/posts/terraform%E4%BA%91%E4%B8%8A%E8%B5%84%E6%BA%90%E5%AF%BC%E5%85%A5/</link><pubDate>Thu, 03 Sep 2026 16:24:03 +0800</pubDate><guid>https://blogs.wuvikr.top/posts/terraform%E4%BA%91%E4%B8%8A%E8%B5%84%E6%BA%90%E5%AF%BC%E5%85%A5/</guid><description>&lt;h1 id="1-为什么要导入云上资源">1. 为什么要&amp;quot;导入&amp;quot;云上资源？&lt;/h1>
&lt;p>很多团队都有这样的经历：最开始用控制台点几下、或者用 CLI 脚本把资源建好了，等资源越攒越多、想标准化管理时，发现这些资源&amp;quot;游离&amp;quot;在 Terraform 之外。&lt;/p>
&lt;p>Terraform 的管理逻辑很简单：&lt;strong>它只认自己 state 文件里记录的资源&lt;/strong>。你在控制台创建的资源，Terraform 根本&amp;quot;看不见&amp;quot;，也不会去动它们。所以要把存量资源管起来，第一步就是&amp;quot;导入&amp;quot;（import）——把云上已有的资源登记进 Terraform 的 state，再补上对应的配置代码。&lt;/p>
&lt;p>导入成功后，这些资源和 Terraform 新建的资源享受完全一样的待遇：能 plan、能 apply、能 diff、能进 CI/CD。&lt;/p>
&lt;h1 id="2-先搞清楚两个概念config-和-state">2. 先搞清楚两个概念：config 和 state&lt;/h1>
&lt;p>这是最容易绕晕的地方，务必先分清：&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align: center">概念&lt;/th>
&lt;th style="text-align: center">是什么&lt;/th>
&lt;th style="text-align: center">谁来写&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align: center">&lt;strong>&lt;code>.tf&lt;/code> 配置（config）&lt;/strong>&lt;/td>
&lt;td style="text-align: center">声明&amp;quot;想要什么&amp;quot;，是给人看的声明式代码&lt;/td>
&lt;td style="text-align: center">手写，或工具自动生成&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align: center">&lt;strong>&lt;code>terraform.tfstate&lt;/code>（state）&lt;/strong>&lt;/td>
&lt;td style="text-align: center">记录&amp;quot;现在实际是什么&amp;quot;，含真实属性（可能有敏感信息）&lt;/td>
&lt;td style="text-align: center">由 apply / import 自动生成&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>关键点：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>导入只会写 state，不会自动写 config&lt;/strong>（除非你用 &lt;code>-generate-config-out&lt;/code> 或 Terraformer）。&lt;/li>
&lt;li>所以完整流程 = &lt;strong>导入进 state + 补齐 config + plan 核对一致&lt;/strong>，三步缺一不可。&lt;/li>
&lt;li>state 含敏感信息，&lt;strong>永远不要提交到 git&lt;/strong>（后面最佳实践会讲远程存储）。&lt;/li>
&lt;/ul>
&lt;p>整体流程可以先看这张图：&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-mermaid" data-lang="mermaid">flowchart TD
A[盘点存量资源: 类型 / ID / 地域] --&amp;gt; B[环境准备: Terraform + provider + RAM 凭证]
B --&amp;gt; C{资源量多少?}
C --&amp;gt;|少| D[import block / terraform import]
C --&amp;gt;|多| E[aliterraformer 批量导入]
D --&amp;gt; F[生成 config + state]
E --&amp;gt; F
F --&amp;gt; G[terraform plan 核对无漂移]
G --&amp;gt; H[清理只读属性 + 纳入 git + OSS 远程 state]
&lt;/code>&lt;/pre>&lt;h1 id="3-三种导入方式怎么选">3. 三种导入方式怎么选&lt;/h1>
&lt;p>&lt;a href="https://help.aliyun.com/zh/terraform/import-resources-into-terraform#63744434ecsis">阿里云官方文档&lt;/a>提供了三种方式，直接放对比表：&lt;/p></description></item><item><title>Terraform 内置函数</title><link>https://blogs.wuvikr.top/posts/terraform%E5%86%85%E7%BD%AE%E5%87%BD%E6%95%B0/</link><pubDate>Thu, 03 Sep 2026 16:06:29 +0800</pubDate><guid>https://blogs.wuvikr.top/posts/terraform%E5%86%85%E7%BD%AE%E5%87%BD%E6%95%B0/</guid><description>&lt;p>写 Terraform 配置的时候，你肯定遇到过这些场景：&lt;/p>
&lt;ul>
&lt;li>想把几个字符串拼起来&lt;/li>
&lt;li>想从一个列表里取第一个元素&lt;/li>
&lt;li>想根据条件选不同的值&lt;/li>
&lt;li>想读取一个 JSON 配置文件&lt;/li>
&lt;/ul>
&lt;p>Terraform 内置了 &lt;strong>100+ 个函数&lt;/strong>，覆盖了字符串处理、集合操作、类型转换、编码解码等各种需求。掌握它们，你的 HCL 代码会从&amp;quot;能跑&amp;quot;变成&amp;quot;优雅&amp;quot;。&lt;/p>
&lt;p>本文挑出&lt;strong>最常用的 20 个函数&lt;/strong>，每个都配上可直接运行的 demo，最后附上最佳实践。&lt;/p>
&lt;hr>
&lt;h1 id="1-字符串函数">1. 字符串函数&lt;/h1>
&lt;h2 id="11-format--格式化字符串">1.1. &lt;code>format()&lt;/code> — 格式化字符串&lt;/h2>
&lt;p>类似其他语言的 &lt;code>sprintf&lt;/code>，用占位符拼接字符串。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-hcl" data-lang="hcl">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">locals&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> env &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;prod&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> region &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;cn-hangzhou&amp;#34;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 输出: &amp;#34;prod-cn-hangzhou-01&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> name &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">format&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%s-%s-01&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">local&lt;/span>.&lt;span style="color:#66d9ef">env&lt;/span>, &lt;span style="color:#66d9ef">local&lt;/span>.&lt;span style="color:#66d9ef">region&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="12-join--用分隔符拼接列表">1.2. &lt;code>join()&lt;/code> — 用分隔符拼接列表&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-hcl" data-lang="hcl">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">locals&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> tags &lt;span style="color:#f92672">=&lt;/span> [&lt;span style="color:#e6db74">&amp;#34;web&amp;#34;, &amp;#34;nginx&amp;#34;, &amp;#34;frontend&amp;#34;&lt;/span>]&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 输出: &amp;#34;web,nginx,frontend&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> csv &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">join&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;,&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">local&lt;/span>.&lt;span style="color:#66d9ef">tags&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="13-split--按分隔符拆分字符串">1.3. &lt;code>split()&lt;/code> — 按分隔符拆分字符串&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-hcl" data-lang="hcl">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">locals&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> str &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;10.0.0.1,10.0.0.2,10.0.0.3&amp;#34;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 输出: [&amp;#34;10.0.0.1&amp;#34;, &amp;#34;10.0.0.2&amp;#34;, &amp;#34;10.0.0.3&amp;#34;]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> ips &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">split&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;,&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">local&lt;/span>.&lt;span style="color:#66d9ef">str&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="14-replace--替换子串">1.4. &lt;code>replace()&lt;/code> — 替换子串&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-hcl" data-lang="hcl">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">locals&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;my-project-dev&amp;#34;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 输出: &amp;#34;my-project-prod&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> new &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">replace&lt;/span>(&lt;span style="color:#66d9ef">local&lt;/span>.&lt;span style="color:#66d9ef">name&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;dev&amp;#34;, &amp;#34;prod&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="15-trimprefix--trimsuffix--去掉前缀后缀">1.5. &lt;code>trimprefix()&lt;/code> / &lt;code>trimsuffix()&lt;/code> — 去掉前缀/后缀&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-hcl" data-lang="hcl">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">locals&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> domain &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;www.example.com&amp;#34;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 输出: &amp;#34;example.com&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> base &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">trimprefix&lt;/span>(&lt;span style="color:#66d9ef">local&lt;/span>.&lt;span style="color:#66d9ef">domain&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;www.&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="16-upper--lower--title--大小写转换">1.6. &lt;code>upper()&lt;/code> / &lt;code>lower()&lt;/code> / &lt;code>title()&lt;/code> — 大小写转换&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-hcl" data-lang="hcl">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">locals&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> env &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;production&amp;#34;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 输出: &amp;#34;PRODUCTION&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> tag &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">upper&lt;/span>(&lt;span style="color:#66d9ef">local&lt;/span>.&lt;span style="color:#66d9ef">env&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h1 id="2-集合函数列表--映射--集合">2. 集合函数（列表 / 映射 / 集合）&lt;/h1>
&lt;h2 id="21-length--获取长度">2.1. &lt;code>length()&lt;/code> — 获取长度&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-hcl" data-lang="hcl">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">locals&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> zones &lt;span style="color:#f92672">=&lt;/span> [&lt;span style="color:#e6db74">&amp;#34;cn-hangzhou-a&amp;#34;, &amp;#34;cn-hangzhou-b&amp;#34;, &amp;#34;cn-hangzhou-c&amp;#34;&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> count &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">length&lt;/span>(&lt;span style="color:#66d9ef">local&lt;/span>.&lt;span style="color:#66d9ef">zones&lt;/span>)&lt;span style="color:#75715e"> # 输出: 3
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="22-element--按索引取值会循环">2.2. &lt;code>element()&lt;/code> — 按索引取值（会循环）&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-hcl" data-lang="hcl">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">locals&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> zones &lt;span style="color:#f92672">=&lt;/span> [&lt;span style="color:#e6db74">&amp;#34;a&amp;#34;, &amp;#34;b&amp;#34;&lt;/span>]&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 索引 2 超出长度，自动取模 → 回到索引 0
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 输出: &amp;#34;a&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> zone &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">element&lt;/span>(&lt;span style="color:#66d9ef">local&lt;/span>.&lt;span style="color:#66d9ef">zones&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;blockquote>
&lt;p>💡 和直接 &lt;code>local.zones[2]&lt;/code> 不同，&lt;code>element()&lt;/code> 不会报错，适合循环创建资源时分配可用区。&lt;/p></description></item><item><title>Terrafrom 基础知识</title><link>https://blogs.wuvikr.top/posts/terraform%E5%9F%BA%E7%A1%80/</link><pubDate>Thu, 03 Sep 2026 12:37:52 +0800</pubDate><guid>https://blogs.wuvikr.top/posts/terraform%E5%9F%BA%E7%A1%80/</guid><description>&lt;h1 id="1-简介">1. 简介&lt;/h1>
&lt;p>&lt;a href="https://developer.hashicorp.com/terraform/intro">Terraform&lt;/a> 是一款&lt;strong>开源的“基础设施即代码（Infrastructure as Code，IaC）”工具&lt;/strong>，由 HashiCorp 公司开发（创始人为 Mitchell Hashimoto）。它的核心作用是用人类可读的配置文件来安全、高效地构建、变更和版本化管理云上和本地的各类基础设施。&lt;/p>
&lt;p>它的主要特点包括：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>基础设施即代码&lt;/strong>：用高阶配置语法描述基础设施，便于版本控制、复用和共享。&lt;/li>
&lt;li>&lt;strong>声明式语言&lt;/strong>：用户只需描述期望的基础设施最终状态，工具自动处理依赖关系和部署顺序；配置语言使用 HCL（也支持 JSON）。&lt;/li>
&lt;li>&lt;strong>执行计划&lt;/strong>：在真正执行前会生成操作计划，避免意外变更。&lt;/li>
&lt;li>&lt;strong>资源图&lt;/strong>：构建资源依赖图并并行处理相互独立的资源。&lt;/li>
&lt;li>&lt;strong>多云支持&lt;/strong>：可与 AWS、Azure、Google Cloud、阿里云等主流云平台集成。&lt;/li>
&lt;/ul>
&lt;p>典型的工作流程包括初始化（&lt;code>terraform init&lt;/code>）、生成计划（&lt;code>terraform plan&lt;/code>）和应用（&lt;code>terraform apply&lt;/code>）三个阶段。Terraform 侧重于定义和管理基础设施结构，常与 Ansible 等侧重于配置管理的工具搭配使用。&lt;/p>
&lt;h1 id="2-核心概念">2. 核心概念&lt;/h1>
&lt;h2 id="21-基础架构即代码-iac">2.1. 基础架构即代码 (IaC)&lt;/h2>
&lt;p>Terraform 允许使用配置文件（而非手动操作或脚本）来定义和管理基础设施。这使基础设施可以像应用程序代码一样进行版本控制、测试和协作。&lt;/p>
&lt;h2 id="22--hcl">2.2 HCL&lt;/h2>
&lt;p>HCL 全称 HashiCorp Configuration Language，是 Terraform 使用的一种特定于域的专用语言，专为基础设施管理设计：&lt;/p>
&lt;ul>
&lt;li>语法简单易学，比 JSON 和 ARM 模板更直观&lt;/li>
&lt;li>支持变量、条件表达式和函数&lt;/li>
&lt;li>提供类型安全和 IntelliSense 支持（在 VS Code 等编辑器中）&lt;/li>
&lt;/ul>
&lt;h2 id="23-providers">2.3. Providers&lt;/h2>
&lt;p>&lt;a href="https://registry.terraform.io/browse/providers">Provider&lt;/a> 是云厂商提供并维护的一个能与云厂商 API 进行交互的插件，其中包含相关资源和数据源对象。Terraform 可以通过 Provider 来管理基础设施。常用的 Providers 有：&lt;/p>
&lt;ul>
&lt;li>AzureRM：管理 Azure 资源&lt;/li>
&lt;li>AWS：管理 AWS 服务&lt;/li>
&lt;li>Kind：使用 Kind 管理 kubernetes 集群&lt;/li>
&lt;li>Docker：管理容器资源&lt;/li>
&lt;li>其他支持的云平台和 SaaS 服务&lt;/li>
&lt;/ul>
&lt;h2 id="24-状态文件-state-file">2.4. 状态文件 (State File)&lt;/h2>
&lt;p>Terraform 会跟踪基础设施的当前状态，包括，组件配置，资源之间的依赖关系等，通过比对配置文件与状态文件，确定需要实施哪些变更。&lt;/p></description></item></channel></rss>