Skip to content

Commit 5b49c49

Browse files
committed
Add Ansible provisioning (optional) for centos 7
1 parent 5b9b16b commit 5b49c49

File tree

5 files changed

+123
-6
lines changed

5 files changed

+123
-6
lines changed

ansible/playbook.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
- name: Customize Machine Image
3+
hosts: all
4+
5+
tasks:
6+
- name: Debug
7+
ansible.builtin.debug:
8+
msg: "Ansible provisiong is enabled!"

centos7/README.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,38 @@ The Packer template in this directory creates a CentOS 7 AMD64 image for use wit
1515
* [MAAS](https://maas.io) 2.3+
1616
* [Curtin](https://launchpad.net/curtin) 18.1-59+
1717

18-
## Customizing the Image
18+
## Customizing the Image with Kickstart
1919

20-
The deployment image may be customized by modifying http/centos7.ks. See the [CentOS kickstart documentation](https://docs.centos.org/en-US/centos/install-guide/Kickstart2/) for more information.
20+
The deployment image may be customized by modifying http/centos7.ks.pkrtpl.hcl. See the [CentOS kickstart documentation](https://docs.centos.org/en-US/centos/install-guide/Kickstart2/) for more information.
21+
22+
## Customizing the Image with Ansible (Optional)
23+
24+
Using Ansible as a provisioner in Packer, alongside modifications to the kickstart file, significantly simplifies the image-building process.
25+
Writing complex configurations directly in the kickstart file, especially within the `%post` section, often leads to issues with escaping sequences and readability.
26+
Inline scripts require careful handling of shell syntax, escape characters, and quotations, which can become cumbersome and error-prone for intricate configurations.
27+
Ansible abstracts these complexities, allowing you to define configurations in a more readable and manageable YAML format.
28+
This approach not only enhances maintainability but also reduces the risk of errors that can occur due to improper escaping or syntax issues in shell scripts.
29+
Additionally, using Ansible as a provisioner allows for the maintenance of a single code base for provisioning across multiple operating systems.
30+
This cross-platform capability simplifies management, reduces duplication of effort,
31+
and ensures consistency in deployments, regardless of the operating system being provisioned.
32+
33+
To run Ansible provisioner following kickstart installation, perform the follwoing steps:
34+
35+
1. Make sure ansible is installed on the machine running packer
36+
2. Add your ansible code to `ansible/playbook.yml`
37+
3. Enable both ansible and ssh provisioners:
38+
39+
```hcl
40+
variable enable_ssh_provisioning {
41+
type = bool
42+
default = true
43+
}
44+
45+
variable enable_ansible_provisioning {
46+
type = bool
47+
default = true
48+
}
49+
```
2150

2251
## Building the image using a proxy
2352

centos7/centos7.pkr.hcl

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ packer {
55
version = "~> 1.0"
66
source = "github.com/hashicorp/qemu"
77
}
8+
ansible = {
9+
version = ">= 1.1.1"
10+
source = "github.com/hashicorp/ansible"
11+
}
812
}
913
}
1014

@@ -55,40 +59,86 @@ variable ks_mirror {
5559
default = "${env("KS_MIRROR")}"
5660
}
5761

62+
variable enable_ssh_provisioning {
63+
type = bool
64+
default = false
65+
}
66+
67+
variable enable_ansible_provisioning {
68+
type = bool
69+
default = false
70+
}
71+
72+
variable ssh_username {
73+
type = string
74+
default = "packer"
75+
}
76+
77+
variable ssh_password {
78+
type = string
79+
default = "packer"
80+
}
81+
82+
variable ssh_user_cleanup {
83+
type = bool
84+
default = true
85+
}
86+
5887
locals {
5988
ks_proxy = var.ks_proxy != "" ? "--proxy=${var.ks_proxy}" : ""
6089
ks_os_repos = var.ks_mirror != "" ? "--url=${var.ks_mirror}/os/x86_64" : var.ks_os_repos
6190
ks_updates_repos = var.ks_mirror != "" ? "--baseurl=${var.ks_mirror}/updates/x86_64" : var.ks_updates_repos
6291
ks_extras_repos = var.ks_mirror != "" ? "--baseurl=${var.ks_mirror}/extras/x86_64" : var.ks_extras_repos
92+
communicator = var.enable_ssh_provisioning == true ? "ssh" : "none"
6393
}
6494

6595
source "qemu" "centos7" {
6696
boot_command = ["<up><tab> ", "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/centos7.ks ", "console=ttyS0 inst.cmdline", "<enter>"]
6797
boot_wait = "3s"
68-
communicator = "none"
98+
communicator = local.communicator
6999
disk_size = "4G"
70100
headless = true
71101
iso_checksum = "file:${var.centos7_sha256sum_url}"
72102
iso_url = var.centos7_iso_url
73103
memory = 2048
74104
qemuargs = [["-serial", "stdio"]]
75105
shutdown_timeout = "1h"
106+
ssh_username = var.enable_ssh_provisioning == true ? var.ssh_username : null
107+
ssh_password = var.enable_ssh_provisioning == true ? var.ssh_password : null
108+
ssh_timeout = "30m"
76109
http_content = {
77110
"/centos7.ks" = templatefile("${path.root}/http/centos7.ks.pkrtpl.hcl",
78111
{
79112
KS_PROXY = local.ks_proxy,
80113
KS_OS_REPOS = local.ks_os_repos,
81114
KS_UPDATES_REPOS = local.ks_updates_repos,
82115
KS_EXTRAS_REPOS = local.ks_extras_repos
116+
SSH_USERNAME = var.ssh_username
117+
SSH_PASSWORD = var.ssh_password
118+
communicator = local.communicator
83119
}
84120
)
85121
}
86-
87122
}
88123

89124
build {
90125
sources = ["source.qemu.centos7"]
91126

127+
provisioner "ansible" {
128+
playbook_file = "../ansible/playbook.yml"
129+
skip_version_check = true
130+
only = var.enable_ansible_provisioning == true ? ["qemu.centos7"] : [""]
131+
}
132+
133+
provisioner "shell" {
134+
script = "../scripts/ssh_provisioning_cleanup.sh"
135+
environment_vars = [
136+
"SSH_USERNAME=${var.ssh_username}",
137+
"SSH_USER_CLEANUP=${var.ssh_user_cleanup}",
138+
]
139+
only = var.enable_ssh_provisioning == true ? ["qemu.centos7"] : [""]
140+
}
141+
92142
post-processor "shell-local" {
93143
inline = [
94144
"SOURCE=${source.name}",

centos7/http/centos7.ks.pkrtpl.hcl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
url ${KS_OS_REPOS} ${KS_PROXY}
2-
poweroff
32
firewall --enabled --service=ssh
43
firstboot --disable
54
ignoredisk --only-use=vda
@@ -19,20 +18,36 @@ zerombr
1918
clearpart --all --initlabel
2019
part / --size=1 --grow --asprimary --fstype=ext4
2120

21+
%{ if communicator == "none" }
22+
poweroff
23+
%{ else }
24+
# Add a provisioner user
25+
user --name='${SSH_USERNAME}' --groups=wheel --password='${SSH_PASSWORD}' --plaintext
26+
27+
# Reboot the system for provisioning
28+
reboot
29+
%{ endif }
30+
2231
%post --erroronfail
2332
# workaround anaconda requirements and clear root password
2433
passwd -d root
2534
passwd -l root
2635

36+
%{ if communicator == "none" }
2737
# Clean up install config not applicable to deployed environments.
2838
for f in resolv.conf fstab; do
2939
rm -f /etc/$f
3040
touch /etc/$f
3141
chown root:root /etc/$f
3242
chmod 644 /etc/$f
3343
done
34-
3544
rm -f /etc/sysconfig/network-scripts/ifcfg-[^lo]*
45+
%{ else }
46+
# Passwordless sudo for provisioner user
47+
echo "${SSH_USERNAME} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${SSH_PASSWORD}
48+
chmod 440 /etc/sudoers.d/${SSH_USERNAME}
49+
50+
%{ endif }
3651

3752
# Kickstart copies install boot options. Serial is turned on for logging with
3853
# Packer which disables console output. Disable it so console output is shown
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
3+
# Clean up install config not applicable to deployed environments.
4+
for f in resolv.conf fstab; do
5+
sudo rm -f /etc/$f
6+
sudo touch /etc/$f
7+
sudo chown root:root /etc/$f
8+
sudo chmod 644 /etc/$f
9+
done
10+
11+
sudo rm -f /etc/sysconfig/network-scripts/ifcfg-[^lo]*
12+
13+
if [ "$SSH_USER_CLEANUP" = "true" ]; then
14+
sudo userdel -r $SSH_USERNAME
15+
fi

0 commit comments

Comments
 (0)