<?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>Iac on 维克的博客</title><link>https://blogs.wuvikr.top/categories/iac/</link><description>Recent content in Iac on 维克的博客</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 09 Oct 2026 11:34:13 +0800</lastBuildDate><atom:link href="https://blogs.wuvikr.top/categories/iac/index.xml" rel="self" type="application/rss+xml"/><item><title>Kubespray 部署和维护 K8s 集群指南</title><link>https://blogs.wuvikr.top/posts/kubespray%E9%83%A8%E7%BD%B2%E5%92%8C%E7%BB%B4%E6%8A%A4k8s%E9%9B%86%E7%BE%A4%E6%8C%87%E5%8D%97/</link><pubDate>Fri, 09 Oct 2026 11:34:13 +0800</pubDate><guid>https://blogs.wuvikr.top/posts/kubespray%E9%83%A8%E7%BD%B2%E5%92%8C%E7%BB%B4%E6%8A%A4k8s%E9%9B%86%E7%BE%A4%E6%8C%87%E5%8D%97/</guid><description>&lt;h1 id="1-简介">1. 简介&lt;/h1>
&lt;p>Kubespray 是 Kubernetes SIGs 官方维护的部署项目，本质是一套经过大量生产环境验证的 Ansible Playbook、Inventory 模板和角色集合。它不发明新的集群模型，而是把 kubeadm 引导、etcd 集群组建、CNI 安装、证书轮换、节点扩缩容与升级这些容易出错的步骤固化为可重复执行的代码。&lt;/p>
&lt;h2 id="11-kubespray-解决了什么问题">1.1 Kubespray 解决了什么问题&lt;/h2>
&lt;p>手动搭一个生产集群的工作量并不仅仅只是简单把 K8s 集群跑起来，而在于：&lt;/p>
&lt;ul>
&lt;li>etcd 节点集群的证书、成员管理、快照备份；&lt;/li>
&lt;li>多控制平面节点下 apiserver 的负载均衡与前端证书 SAN；&lt;/li>
&lt;li>kubelet 配置（cgroup 驱动、预留资源、镜像垃圾回收、最大 Pod 数）；&lt;/li>
&lt;li>CNI 插件与内核网络参数、iptables/nftables 后端的匹配；&lt;/li>
&lt;li>证书到期轮换、跨小版本顺序升级、节点下线清理。&lt;/li>
&lt;/ul>
&lt;p>这些工作做一次可以靠文档，做十次就得靠自动化。Kubespray 的价值就在于它把这些工程细节沉淀成了一套&lt;strong>符合生产环境最佳实践的可重复执行代码&lt;/strong>，你只需要在默认值的基础上少量改动，而不是自己编写和维护大量的脚本。&lt;/p>
&lt;h2 id="12-和其他工具对比">1.2 和其他工具对比&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>工具&lt;/th>
&lt;th>Kubespray&lt;/th>
&lt;th>kubeadm&lt;/th>
&lt;th>Rancher&lt;/th>
&lt;th>OpenShift(OKD)&lt;/th>
&lt;th>kops&lt;/th>
&lt;th>KubeKey(kk)&lt;/th>
&lt;th>k3s&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>核心定位&lt;/strong>&lt;/td>
&lt;td>Ansible驱动，生产级离线部署K8s集群&lt;/td>
&lt;td>K8s官方最小化集群引导工具&lt;/td>
&lt;td>企业级K8s全生命周期管理平台&lt;/td>
&lt;td>红帽出品，基于K8s的企业容器平台&lt;/td>
&lt;td>AWS专用K8s集群部署工具&lt;/td>
&lt;td>KubeSphere社区开源部署工具，中文友好&lt;/td>
&lt;td>Rancher出品轻量K8s发行版&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>底层引擎&lt;/strong>&lt;/td>
&lt;td>Ansible&lt;/td>
&lt;td>Go原生二进制&lt;/td>
&lt;td>容器+WebUI&lt;/td>
&lt;td>容器/Operator&lt;/td>
&lt;td>Go，调用AWS API&lt;/td>
&lt;td>Go二进制，封装kubeadm&lt;/td>
&lt;td>裁剪K8s单二进制&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>适用环境&lt;/strong>&lt;/td>
&lt;td>裸金属、VMware、私有云、离线环境&lt;/td>
&lt;td>裸金属/虚拟机/云主机，在线为主&lt;/td>
&lt;td>公有云、私有云、边缘，多集群统一管理&lt;/td>
&lt;td>企业私有/混合云，偏向生产企业&lt;/td>
&lt;td>&lt;strong>仅限AWS&lt;/strong>公有云&lt;/td>
&lt;td>裸机/虚拟机，私有化离线场景&lt;/td>
&lt;td>低配服务器、边缘、开发/小生产&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>离线部署&lt;/strong>&lt;/td>
&lt;td>✅ 完美支持，可打包离线介质&lt;/td>
&lt;td>⚠️ 支持但麻烦，需要手动下载镜像/二进制&lt;/td>
&lt;td>✅ 支持离线airgap安装&lt;/td>
&lt;td>✅ 官方提供离线方案&lt;/td>
&lt;td>❌ 依赖AWS云API，不适合离线&lt;/td>
&lt;td>✅原生支持打包离线包&lt;/td>
&lt;td>✅离线包&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>集群维护&lt;/strong>&lt;/td>
&lt;td>Ansible playbook升级、扩容、替换节点；版本升级稳定&lt;/td>
&lt;td>仅引导集群，&lt;strong>不负责后续集群运维&lt;/strong>，升级操作繁琐&lt;/td>
&lt;td>Web界面一键升级、扩缩容，多集群统一监控告警&lt;/td>
&lt;td>Operator管理集群，自动化运维能力强&lt;/td>
&lt;td>集群升级、节点替换由kops命令管理&lt;/td>
&lt;td>一键HA、扩容升级，可配套KubeSphere控制台&lt;/td>
&lt;td>一行命令运维，嵌入式etcd HA&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>高可用&lt;/strong>&lt;/td>
&lt;td>✅ 内置etcd三副本、控制面HA方案&lt;/td>
&lt;td>需要手动搭建HA（负载均衡+多master）&lt;/td>
&lt;td>✅ 自动支持HA，内置负载均衡方案&lt;/td>
&lt;td>✅ 默认HA架构&lt;/td>
&lt;td>✅ AWS上自动搭建控制面HA&lt;/td>
&lt;td>✅一键HA，内置负载均衡&lt;/td>
&lt;td>✅内置HA（嵌入式etcd）&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>网络插件&lt;/strong>&lt;/td>
&lt;td>内置Calico/Flannel/Cilium等多种CNI可选&lt;/td>
&lt;td>仅提供基础CNI对接，需自行部署CNI&lt;/td>
&lt;td>内置多种CNI，UI可视化配置&lt;/td>
&lt;td>默认OVN-Kubernetes，也可Calico&lt;/td>
&lt;td>默认Calico，可自定义CNI&lt;/td>
&lt;td>Calico等CNI可选&lt;/td>
&lt;td>Flannel默认，支持替换CNI&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>存储支持&lt;/strong>&lt;/td>
&lt;td>对接本地卷、Ceph、Longhorn等，ansible角色集成&lt;/td>
&lt;td>仅提供CSI标准，存储需要自己部署&lt;/td>
&lt;td>内置存储管理，支持Longhorn等&lt;/td>
&lt;td>内置CSI+本地存储方案&lt;/td>
&lt;td>对接AWS EBS等云存储&lt;/td>
&lt;td>对接Longhorn、Ceph、本地存储&lt;/td>
&lt;td>支持本地存储、CSI&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>版本适配&lt;/strong>&lt;/td>
&lt;td>紧跟K8s社区版本，滞后一小段时间&lt;/td>
&lt;td>K8s官方同步发布&lt;/td>
&lt;td>支持多K8s版本，统一纳管不同版本集群&lt;/td>
&lt;td>OKD版本独立，和上游K8s有差异&lt;/td>
&lt;td>紧跟AWS支持的K8s版本&lt;/td>
&lt;td>跟随上游kubeadm&lt;/td>
&lt;td>Rancher维护稳定版本&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>学习成本&lt;/strong>&lt;/td>
&lt;td>中等，需要懂Ansible&lt;/td>
&lt;td>低，上手简单，适合测试集群&lt;/td>
&lt;td>低，WebUI友好，运维门槛低&lt;/td>
&lt;td>高，体系庞大，有专属概念&lt;/td>
&lt;td>中等，熟悉AWS即可快速上手&lt;/td>
&lt;td>中等，中文文档友好&lt;/td>
&lt;td>很低，上手极快&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>典型场景&lt;/strong>&lt;/td>
&lt;td>裸金属机房、私有化项目、需要批量部署大量集群、等保离线环境&lt;/td>
&lt;td>实验室、POC测试、小规模简单集群&lt;/td>
&lt;td>多集群管理、混合云、需要统一权限/审计的企业&lt;/td>
&lt;td>大型企业生产环境，需要完整容器安全、合规能力&lt;/td>
&lt;td>AWS云上快速搭建销毁K8s集群&lt;/td>
&lt;td>中小企业裸机/VM离线部署，可选KubeSphere控制台&lt;/td>
&lt;td>资源有限、边缘、小生产集群&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>缺点&lt;/strong>&lt;/td>
&lt;td>Ansible串行执行，大规模集群部署慢；无WebUI；故障排查需要Ansible基础&lt;/td>
&lt;td>没有集群生命周期管理，生产HA搭建工作量大；缺少监控日志等附加组件&lt;/td>
&lt;td>资源开销大；底层K8s被封装，深度定制复杂；商业版收费&lt;/td>
&lt;td>闭源企业版昂贵；架构重，资源消耗高；学习曲线陡峭&lt;/td>
&lt;td>只能跑在AWS，无法裸金属/其他云使用&lt;/td>
&lt;td>依赖kubeadm；底层封装，深度排障需要kubeadm知识；KubeSphere额外耗资源&lt;/td>
&lt;td>裁剪部分组件，重型大规模生产不推荐；和标准K8s有细微差异&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>国内中小企业热度&lt;/strong>&lt;/td>
&lt;td>⭐⭐⭐ 更多集成商使用，中小企业自用偏少&lt;/td>
&lt;td>⭐⭐⭐⭐⭐ 最高，几乎所有运维都学这个&lt;/td>
&lt;td>⭐⭐⭐⭐ 多集群场景热门&lt;/td>
&lt;td>⭐⭐ 大型企业为主，中小企业很少用&lt;/td>
&lt;td>⭐ 国内几乎不用&lt;/td>
&lt;td>⭐⭐⭐⭐ 私有化中小企业热门&lt;/td>
&lt;td>⭐⭐⭐⭐ 小集群/边缘场景热门&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h1 id="2-底层架构和设计">2. 底层架构和设计&lt;/h1>
&lt;p>&lt;strong>关键核心设计&lt;/strong>：&lt;/p></description></item><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>