Packer现在支持HCL2,所以我重写了现有的Json格式代码。
我叫寺冈,是一名基础设施工程师。
Packer 迎来了期待已久的更新。
终于支持HCL2了!
这次,我尝试基于HCL2重写现有Json编写的代码,因此
我想在比较每个代码的同时进行总结。
打包机是什么?
一个 CLI 工具,可以创建多云兼容的黄金映像。
此类黄金镜像创建工具
与 Immutable Infrastructure 和蓝绿部署高度兼容,
在 AutoScaling 等频繁重复创建和销毁服务器的环境中非常有用。
HashiCorp 继续开发并用 Golang 编写。
Terraform也是一个很有名的工具,所以可能很多人都熟悉它。
支持创建 Docker 镜像、VMware 等虚拟机管理程序类型的机器镜像
以及 AWS、GCP 和 Azure 等主流云服务虽然它与许多服务(Packer 中称为构建器)兼容,但
优点是您可以为所有构建器以通用格式编写代码和处理。
之前只能写成Json格式,但是
从1.5版本开始支持HCL2格式。
在撰写本文时(2020/03/31),它仍处于测试阶段,
因此在生产环境中使用它之前最好仔细测试它。
什么是HCl?
它代表 HashiCorp 配置语言,也是由 HashiCorp 开发的。
在实现方面,它与 Json 兼容,但由于它是一种专有语言,因此您可以编写自己的与 Json 完全不同的独特描述。
它旨在用作命令行工具,并且已经得到 Terraform 支持一段时间了,所以
我认为编写 tf 文件的人会熟悉它。
顺便说一句,有两个不同的版本,HCL1和HCL2,目前HCL2是主流。
我们来写一个Packer模板(Json)
Packer通过编写称为模板的东西来创建图像,但
我想用HCL2编写它,同时将模板的内容与Json格式进行比较。
首先我们看一下Json格式写的是什么。
{ "builders": [ { "type": "amazon-ebs", "region": "{{user `region`}}", "source_ami_filter": { "filters": { "name": "{{user `ami_name`}}*" }, "owners": [ "self" ], "most_recent": true }, "instance_type": "{{user `instance_type`}}", "ssh_username": "{{user ` ssh_username`}}", "ami_name": "{{user `ami_name`}}_{{timestamp}}", "tags": { "Name": "{{user `ami_name`}}_{{timestamp} }" }, "iam_instance_profile": "{{user `iam_instance_profile`}}" } ], "provisioners": [ { "type": "shell", "inline": [ "sudo yum -y update" ] } ] }
{{user `ami_name`}} 等部分是变量,
存储的值写入单独的文件中。
{“ssh_username”:“ec2-user”,“region”:“ap-northeast-1”,“instance_type”:“t3.micro”,“ami_name”:“ami-packer-test”,“iam_instance_profile”:“角色打包测试”}
使用此模板文件
$ packer build main.json -var-file=variables.json
通过执行该命令,
您可以构建图像,同时从variables.json中读取要存储在变量中的值。
如果你按照上面模板的内容构建,
- 使用 source_ami_filter 中写入的内容搜索基本 AMIID
- 根据与搜索匹配的 AMI 启动构建过程
- 从基础 AMI 启动新的 EC2 实例
- 创建临时密钥对以登录您的 EC2 实例
- 使用 SSH 登录实例并执行配置程序中描述的流程
- 停止 EC2 实例
- 从已停止的实例获取 AMI
- 获取完成后删除实例
执行一系列过程。
IAM角色可以用来获取AMI信息,因此
执行packer命令的EC2实例上
预先设置了执行所需的IAM角色
IAM 角色所需的权限总结如下。
https://packer.io/docs/builders/amazon.html
尝试编写 Packer 模板 (HCL2)
那么,如果我们将上面的Json重写为HCL2会发生什么呢?
首先,我们将写入要存储在变量中的值。
使用以下两个文件。
变量.pkrvars.hcl
ssh_username =“ec2-user”区域=“ap-northeast-1”instance_type =“t3.micro”ami_name =“ami-packer-test”iam_instance_profile =“role-packer-test”
变量.pkr.hcl
变量“ssh_username”{ 类型 = 字符串描述 =“SSH 用户名” } 变量“区域”{ 类型 = 字符串描述 =“AWS 区域” } 变量“instance_type”{ 类型 = 字符串描述 =“EC2 实例类型” } 变量“ami_name” " { 类型 = 字符串描述 = "EC2 AMI 名称" } 变量 "iam_instance_profile" { 类型 = 字符串描述 = "EC2 IAM 实例配置文件" }
将要存储在变量中的值写入variables.pkrvars.hcl中。
在Json中,它是“值名称:值”,但在HCL2中,它是“值名称=值”。
在HCL2中使用variable来表示变量。
和编程语言一样,有类型的概念,
这次我们都使用字符串类型变量。
此外,
- 数字类型(数字)
- 列表类型(列表)
- 地图类型(地图)
- 布尔类型(bool)
ETC。
接下来,我们将描述实际的构建处理部分。
使用以下两个文件。
来源.pkr.hcl
## 源 source "amazon-ebs" "example" {region = var.region ami_name = "${var.ami_name}_{{timestamp}}" instance_type = var.instance_type iam_instance_profile = var.iam_instance_profile ssh_username = var.ssh_username source_ami_filter { Owner = ["self"]most_recent = true 过滤器 { virtualization-type = "hvm" name = "${var.ami_name}*" root-device-type = "ebs" } } 标签 { Name = "${var" .ami_name}_{{时间戳}}" } }
构建.pkr.hcl
## 构建构建 { 来源 = [ "source.amazon-ebs.example" ] 配置程序 "shell" { inline = [ "sudo yum -y update" ] } }
正如您所看到的,在 Json 格式中,一个文件中编写的内容
可以分为单独的文件,用于源文件和构建文件。
HCL2的另一个功能是您可以在代码中间插入注释。
可以使用“var.变量名”来引用变量。
在 build.pkr.hcl 中,我们读取源设置并
在配置程序部分中写入要在构建期间执行的处理。
源部分是列表类型,因此您可以指定多个源,如下所示。
来源= [“source.amazon-ebs.example”,“source.amazon-ebs.example2”]
运行构建时,移动到模板文件所在的目录。
$ packer build -var-file=variables.pkrvars.hcl ./
这将读取并执行当前目录中的所有文件。
当前问题
Packer有一个validate命令来检查语法,但是
用HCL编写时不能使用该命令。
我期待未来的更新。
https://github.com/hashicorp/packer/issues/8538
概括
Packer 是使用云服务实践 DevOps 的有用工具。
Packer 本身很容易合并到 CI/CD 流程中,因此我们
鼓励每个人都尝试使用它。