)
文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载本指南是 90DaysOfDevOps 挑战第 58 天的技术笔记围绕 HashiCorp Configuration LanguageHCL与 Terraform 展开你将掌握 Terraform 配置文件的三大核心构成Provider、Resource、State学会用terraform init / plan / apply / destroy四个命令完成从下载插件到销毁资源的完整生命周期并能结合仓库内的 Hello-world、Virtualbox、Docker、Kubernetes 示例代码把同一套声明式理念迁移到不同的基础设施平台。HCLTerraform 的声明式配置语言在动手用 Terraform 创建资源之前必须先了解它的配置语言 HCL。在 90DaysOfDevOps 的旅程中我们已经接触过几种脚本与编程语言先是 Go 编程语言然后是 bash 脚本在 网络自动化 环节还用到了一点 Python。HCL 是这条学习路线上的又一个新语言它的语法与 JSON 兼容超集可以嵌套注释并原生支持块结构、表达式和函数调用。如果你是第一次见到 HCL它看上去可能有点唬人但它的设计目标恰恰是简单而强大它不追求像通用编程语言那样表达任意逻辑而是专注于以声明方式描述最终想要达到的状态desired state。这意味着我们写配置时关注要什么而不是怎么一步步做。从整个 Terraform 的组成来看可以拆成两层Terraform Core由两部分组成一是我们本课要重点讲解的代码configuration二是状态stateProvider 层负责与目标环境通信并执行部署。例如 AWS 有hashicorp/awsprovider、Azure 有对应的 provider此外还有数百个社区维护的 provider覆盖各类云平台与虚拟化环境。在真实生产环境中Terraform 通常用于向公有云AWS、Google Cloud、Microsoft Azure或虚拟化平台VMware、Microsoft Hyper-V、Nutanix AHV部署基础设施在公有云里它的能力远不止自动创建虚拟机还包括 PaaS 负载、VPC、安全组Security Group等全套网络与业务资源。不过本文以及后续第 59 天的示例选择了可以完全本地运行、免费的 VirtualBox 作为演示平台其理念与云端完全一致同样可以推广到 Docker 或 Kubernetes。动手前的准备本课示例可以在任何操作系统上本地运行。第一段示例面向 AWS 部署因此需要在系统上安装 Terraform CLI安装 AWS CLI 并完成账号配置aws configure准备一个存放.tf文件的目录约定俗成的主文件名是main.tf。如果暂时没有云账号也可以直接跳到仓库中 IaC 目录 的本地示例Virtualbox、Docker、Kubernetes先跑通流程再回到 AWS 场景。Provider声明 Terraform 与目标平台的桥梁在一个.tf文件通常叫main.tf的顶部我们会先声明 provider。provider 是 Terraform 与目标平台 API 之间的适配器Terraform 通过它把声明式配置翻译成对平台 API 的调用。terraform { required_providers { aws { source hashicorp/aws version ~ 3.0 } } }这里的source hashicorp/aws表示该 provider 由 HashiCorp 官方维护或发布默认情况下引用的是 Terraform Registry 上可用的 provider当然你也可以编写自己的 provider 并在本地使用或自行发布到 Registry。声明 provider 后还可以通过provider块补充连接参数例如指定要部署到的 AWS 区域provider aws { region ap-southeast-1 // 资源需要部署到的区域 }仓库中其他 provider 的写法也遵循同一套结构方便你对照体会换平台只换 provider写法不变的理念Virtualbox 示例 使用社区 providerterra-farm/virtualbox0.2.2-alpha.1Docker 示例 使用kreuzwerker/docker2.16.0Kubernetes 示例 使用官方hashicorp/kubernetes 2.0.0并通过config_path ~/.kube/config指定 kubeconfig。从这些示例可以看出required_providers中的version约束是 provider 版本管理的关键~ 3.0表示锁定在 3.x 系列允许 3.x 的补丁版本这是生产环境中保证可重复部署的常见做法。Resource用代码声明你要创建的基础设施对象如果说 provider 解决的是Terraform 如何与平台对话那么resource资源解决的就是我们到底要部署什么。Resource 是 Terraform 配置文件中另一个核心组件用来描述一个或多个基础设施对象比如 EC2、负载均衡器、VPC 等。一个 resource 块的语法要点如下resource关键字后跟资源类型如aws_instance和本地名称如90daysofdevops资源类型 本地名称共同构成该资源的唯一标识符供配置内部相互引用。resource aws_instance 90daysofdevops { ami data.aws_ami.instance_id.id instance_type t2.micro availability_zone us-west-2a security_groups [aws_security_group.allow_web.name] user_data -EOF #! /bin/bash sudo yum update sudo yum install -y httpd sudo systemctl start httpd sudo systemctl enable httpd echo h1Deployed via Terraform/h1 | sudo tee /var/www/html/index.html EOF tags { Name Created by Terraform } }上面这段代码在创建 EC2 实例的同时通过user_data在实例启动时执行了一段 bash 脚本更新系统、安装httpdApache Web Server、启动并设置开机自启最后写入一个Deployed via Terraform的首页。这是 Terraform 最常见的实践之一——基础设施与初始化配置一起声明实例一上线就是一个可用的 Web 服务。一个完整的 main.tf从配置到可重复部署把 provider 与 resource 组合起来一个完整可用的main.tf大致如下terraform { required_providers { aws { source hashicorp/aws version ~ 3.27 } } required_version 0.14.9 } provider aws { profile default region us-west-2 } resource aws_instance 90daysofdevops { ami ami-830c94e3 instance_type t2.micro availability_zone us-west-2a user_data -EOF #! /bin/bash sudo yum update sudo yum install -y httpd sudo systemctl start httpd sudo systemctl enable httpd echo h1Deployed via Terraform/h1 | sudo tee /var/www/html/index.html EOF tags { Name ExampleAppServerInstance } }注意这里新增了两个元素required_version 0.14.9限定 Terraform CLI 的最低版本provider aws块通过profile default指定使用 AWS 凭据配置中的默认 profile。这段代码会部署一个非常简单的 Web 服务器 EC2 实例。这类配置最大的价值在于可重复性无论执行多少次只要代码不变产出的结果就保持一致前提是代码本身没有写错。整个过程无需人工干预——这正是基础设施即代码IaC的核心意义。Hello-World最小可运行的 Terraform 模块像所有好的脚本语言一样我们从 hello-world 场景开始认识 Terraform 的完整工作流。下面这个极简模块不创建任何资源只输出一行文本它的实际文件就保存在仓库的 IaC/Hello-world/main.tfterraform { # 该模块当前仅在 Terraform 0.13.x 下测试。为便于升级我们设置最低版本为 0.12.26 # 因为该版本起支持带 source URL 的 required_providers可与 0.13.x 代码向前兼容。 required_version 0.12.26 } # The simplest possible Terraform module: it just outputs Hello, World! output hello_world { value Hello, 90DaysOfDevOps from Terraform }这个模块展示了output块它把某个值暴露给调用方在模块被引用时尤为重要。不过这段代码并不能开箱即用——要真正运行 Terraform 代码必须先执行一系列 CLI 命令。Terraform CLI 四大命令在终端中进入存放main.tf的目录可以是本仓库的 IaC/Hello-world 目录也可以是用上面的代码新建的目录然后依次执行以下命令。terraform init初始化目录并下载 Providerterraform init任何目录在运行 Terraform 代码之前都必须执行terraform init。初始化过程会下载并安装配置中声明的 provider 插件上面 hello-world 例子中没有 provider而 AWS 例子则会下载hashicorp/aws。建议在运行terraform init前后分别查看一次目录树你会看到多出了.terraform目录——provider 插件和模块就被存放在那里这也是理解 Terraform 工作目录结构的好方法。terraform plan预览将要发生的变更terraform planterraform plan会生成一份执行计划execution plan让你预先查看Terraform 将对基础设施做哪些更改。下面的输出来自 hello-world 示例由于它只有输出没有资源所以不会显示创建步骤如果是一个 EC2 实例配置这里会列出将要创建的每一个资源及其属性。terraform apply应用代码、部署资源terraform apply在完成初始化、通过 plan 确认变更符合预期之后就可以用apply部署代码。apply内置了一道安全机制它同样会先展示将要执行的计划并要求你输入yes确认后才会真正执行。输入yes后代码即被部署。就 hello-world 而言输出并不惊艳但你能看到我们在代码中定义的output值被如实打印出来terraform destroy销毁已部署的资源terraform destroy如果部署过真实资源、想要全部清理掉就使用terraform destroy。它同样需要输入yes确认你也可以在apply和destroy命令末尾追加--auto-approve跳过人工确认。但建议仅在学习和测试场景使用该捷径——因为资源一旦销毁往往比创建时更快全部消失往往只是一瞬间的事。四个命令的职责可以这样总结命令作用terraform init准备好项目目录下载并安装配置中声明的 providerterraform plan展示下一步基于代码将创建、修改哪些资源terraform apply真正部署代码中定义的资源terraform destroy销毁项目中已创建的资源与之对应的配置文件中也有两个必须掌握的概念providersTerraform 通过 provider 与目标平台 API 通信的方式resources我们想用代码部署的内容。Terraform State基础设施的世界地图运行 Terraform 后你的目录中会出现一个状态文件state file。对 hello-world 而言它非常简单本质是一个 JSON 文件可以理解为Terraform 眼中的世界the representation of the world according to Terraform{ version: 4, terraform_version: 1.1.6, serial: 1, lineage: a74296e7-670d-0cbb-a048-f332696ca850, outputs: { hello_world: { value: Hello, 90DaysOfDevOps from Terraform, type: string } }, resources: [] }关于状态文件有三条必须牢记的实践敏感数据风险状态文件会如实记录资源属性其中可能包含敏感信息因此务必小心加入 .gitignore最佳实践是把*.tfstate文件加入.gitignore避免在上传仓库时泄露默认位置与远程存储默认状态下文件与项目代码同目录但也支持存放在远程位置。在生产环境中状态文件通常存放在共享位置例如 S3 bucket另一可选方案是 Terraform Cloud托管付费服务5 个用户以内免费。远程存储状态的好处包括敏感数据加密支持团队协作便于自动化代价是可能引入额外的复杂度。在仓库中继续深入把同一套理念迁移到其他平台本课的全部示例代码都保存在仓库的 2022/Days/IaC 目录下除了 Hello-world 与 AWS 场景你还可以对照阅读以下实现来加深理解Virtualbox/virtualbox.tf使用count 2配合format(node-%02d, count.index 1)批量创建两台虚拟机并输出其 IP 地址——这是用代码声明两台 VM的典型写法Docker/docker.tf声明一个 nginx 镜像与容器并通过ports块把容器 80 端口映射到宿主机 8000 端口Kubernetes/kubernetes.tf声明 namespace、deployment 与 NodePort service展示 HCL 中的引用语法如kubernetes_namespace.test.metadata.0.name引用先前资源的属性Terratest/examples包含完整的 AWS 生产风格示例其中 vars.tf 演示了variable与map(string)默认值的定义provider.tf 演示了通过var.AWS_ACCESS_KEY等变量注入凭据的方式terraform.tfvars 则是给变量赋值的标准入口文件。从这些源码可以看出Provider、Resource、State 与 CLI 四大命令构成了 Terraform 的全部心智模型而 HCL 的块结构、资源引用和变量机制则是贯穿其中的语言骨架。掌握本课内容后你可以继续进入 Day 59用 Terraform 与变量在 VirtualBox 创建虚拟机把这里的声明式理念应用到本地虚拟化平台完成一次完整的创建 - 变更 - 销毁闭环实战。无法成文 /无法成文赞分享文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载相关推荐90DaysOfDevOps Day 58HashiCorp 配置语言HCL与 Terraform 从零上手90DaysOfDevOps Day 58HashiCorp 配置语言HCL与 Terraform 从零上手 HashiCorp 配置语言HCL是 T文档/教程90DaysOfDevOps 之 HCL 与 Terraform 入门Provider、Resource、State 与 CLI 全流程解析90DaysOfDevOps 之 HCL 与 Terraform 入门Provider、Resource、State 与 CLI 全流程解析 本篇文章是 90文档/教程90DaysOfDevOps 第 58 天HashiCorp Configuration Language (HCL) 与 Terraform 从零上手90DaysOfDevOps 第 58 天HashiCorp Configuration Language HCL 与 Terraform 从零上手 本篇文章文档/教程上一篇LLaVA-v1.6-34B部署实战本地、云端和边缘计算的完整方案下一篇百度网盘秒传链接提取脚本完整指南彻底告别文件分享失效的终极解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考