创建可复用的Packer模板的惯用方法

42次阅读
没有评论

问题描述

正在创建大约10-12个Packer模板,这些模板几乎都以相同的方式工作。它们使用相同的构建器(Amazon EBS),只有一些AMi名称上的小变化,并且几乎使用相同的配置(Ansible Remote)- 有时会有额外的变量,有时会有多个playbook。

但是,大部分Packer模板都保持不变。用户已经了解到可以使用变量将一些可变的值放在文件的一个位置。但是,他希望减少模板中的重复代码。

他考虑过使用一个使用jq或类似工具的包装shell脚本。但是,他添加的每一层复杂性都会给其他人带来更多需要学习的内容。尽管尽力寻找,但他似乎无法找到在Packer中’官方’的惯用方法。

用户想知道是否有一种惯用的方法来实现这一点 – 或者至少有一种普遍接受的方法?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1:使用HCL2和source blocks

利用HCL2语法是解决这个问题的正确方法。可以使用不同的source blocks来定义不同的源,并将源分配给构建器,甚至可以根据源的条件来执行配置管理和后处理。以下是一个基本示例,根据hashicorp文档对多个源和ansible进行了适应:

source "amazon-ebs" "first-example" {
    ...
}
source "amazon-ebs" "second-example" {
    ...
}

build {
    name = "my_build"
    sources = [
        "source.amazon-ebs.first-example",
        "source.amazon-ebs.second-example"
    ]

    # 在所有源上运行的通用配置管理
    provisioner "ansible" {
        playbook_file = "common.yml"
    }

    # 只在第一个源上运行的配置管理
    provisioner "ansible" {
        only = ["source.amazon-ebs.first-example"]
        playbook_file = "playbook-a.yml"
    }

    # 从第二个源排除的配置管理
    provisioner "ansible" {
        except = ["source.amazon-ebs.second-example"]
        playbook_file = "playbook-b.yml"
    }
}

这种方法允许根据需要定义不同的源,使得从同一个Packer构建命令中生成多云、架构、分发和用途的镜像成为可能。

方案2:使用自定义包装脚本

另一种方法是编写自定义的包装脚本来管理模板的运行顺序。你可以使用docker run命令来手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。

示例:

以下是一个简单的bash脚本示例,可以在容器A启动后启动容器B:

#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
  sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b

在这个示例中,我们首先使用docker run命令启动容器A,并将其命名为container_a。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo命令来测试)。一旦容器A就绪,我们再使用docker run命令启动容器B,并将其命名为container_b

请注意,使用自定义脚本来管理容器的启动顺序可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系设置正确。这种方法适用于那些希望更多自定义控制的用户,但也可能增加一些维护和学习的负担。

方案3:使用外部工具

Packer已经主动决定不构建此类功能。这个问题更好地由其他工具(如jq等)解决。我们认为利用Packer的最佳方法是在需要更多模板创建方式时对其进行包装。

可以在任何编程语言中轻松创建JSON,这在创建模板时提供了无限的表达能力。操作模板的一个很好的方式是在jinja2中定义模板,并在Python中预处理它。这种方法允许更大的灵活性和定制性,但也可能需要更多的开发工作。

以上是几种解决问题的方法,具体取决于你的需求和偏好。无论选择哪个方法,都需要根据情况选择最适合你团队的方法。

正文完