packer/main.pkr.hcl (145 lines of code) (raw):
# Copyright 2021 ${var.prefix} LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##########
# LOCALS #
##########
locals {
slurm_version = regex("^(?P<major>\\d{2})\\.(?P<minor>\\d{2})(?P<end>\\.(?P<patch>\\d+)(?P<sub>-(?P<rev>\\d+\\w*))?|\\-(?P<meta>latest))$|^b:(?P<branch>.+)$", var.slurm_version)
slurm_branch = local.slurm_version["branch"] != null ? replace(local.slurm_version["branch"], ".", "-") : null
slurm_semver = join("-", compact([local.slurm_version["major"], local.slurm_version["minor"], local.slurm_version["patch"], local.slurm_branch]))
ansible_dir = "../ansible"
scripts_dir = "../scripts"
ansible_vars = {
slurm_version = var.slurm_version
install_cuda = var.install_cuda
nvidia_version = var.nvidia_version
install_ompi = var.install_ompi
install_lustre = var.install_lustre
install_gcsfuse = var.install_gcsfuse
monitoring_agent = var.monitoring_agent
}
parse_version = regex("^(?P<major>\\d+)(?:\\.(?P<minor>\\d+))?(?:\\.(?P<patch>\\d+))?|(?P<branch>\\w+)$", var.slurmgcp_version)
branch = local.parse_version["branch"] != null ? replace(local.parse_version["branch"], ".", "-") : null
version = join("-", compact([local.parse_version["major"], local.parse_version["minor"], local.parse_version["patch"], local.branch]))
prefix_str = try(length(var.prefix), 0) > 0 ? "${var.prefix}-" : ""
root_str = "slurm-gcp-${local.version}"
variant_str = try(length(var.variant), 0) > 0 ? "-${var.variant}" : ""
# If image_family_alt is set, use it instead of source_image_family
image_os_name = try(length(var.image_family_alt), 0) > 0 ? var.image_family_alt : var.source_image_family
generated_family = "${local.prefix_str}${local.root_str}-${local.image_os_name}${local.variant_str}"
# if image_family_name is set, use it for image_family instead of the generated one.
image_family = try(length(var.image_family_name), 0) > 0 ? var.image_family_name : local.generated_family
}
##########
# SOURCE #
##########
source "googlecompute" "image" {
### general ###
project_id = var.project_id
zone = var.zone
### image ###
source_image_project_id = [var.project_id, var.source_image_project_id]
skip_create_image = var.skip_create_image
### network ###
network_project_id = var.network_project_id
subnetwork = var.subnetwork
tags = var.tags
### service account ###
service_account_email = var.service_account_email
scopes = var.service_account_scopes
### image ###
source_image = var.source_image
source_image_family = var.source_image_family
image_name = "${local.image_family}-{{timestamp}}"
image_family = local.image_family
image_description = "slurm-gcp-v5"
image_licenses = var.image_licenses
image_labels = var.labels
### ssh ###
ssh_username = var.ssh_username
ssh_password = var.ssh_password
ssh_clear_authorized_keys = true
use_iap = var.use_iap
use_os_login = var.use_os_login
temporary_key_pair_type = "ed25519"
#temporary_key_pair_bits = 0
### instance ###
instance_name = "${local.image_family}-{{timestamp}}"
machine_type = var.machine_type
preemptible = var.preemptible
labels = var.labels
### disk ###
disk_size = var.disk_size
disk_type = var.disk_type
on_host_maintenance = var.on_host_maintenance
### metadata ###
metadata = {
block-project-ssh-keys = "TRUE"
shutdown-script = <<-EOT
#!/bin/bash
userdel -r ${var.ssh_username}
sed -i '/${var.ssh_username}/d' /var/lib/google/google_users
EOT
}
state_timeout = "10m"
}
#########
# BUILD #
#########
build {
### general ###
name = "slurm-gcp"
sources = ["sources.googlecompute.image"]
### provision Slurm ###
provisioner "ansible" {
command = "${var.ansible_command}"
playbook_file = "${local.ansible_dir}/playbook.yml"
galaxy_file = "${local.ansible_dir}/requirements.yml"
ansible_env_vars = [
"ANSIBLE_CONFIG=${local.ansible_dir}/ansible.cfg",
]
extra_arguments = [
"--extra-vars",
"${jsonencode(local.ansible_vars)}",
]
use_proxy = false
}
dynamic "provisioner" {
# using labels this way effectively creates 'provisioner "ansible"' blocks
labels = ["ansible"]
for_each = var.extra_ansible_provisioners
content {
command = "${var.ansible_command}"
playbook_file = provisioner.value.playbook_file
roles_path = provisioner.value.galaxy_file
extra_arguments = provisioner.value.extra_arguments
user = provisioner.value.user
}
}
### post processor ###
post-processor "manifest" {
output = "manifest.json"
strip_path = false
strip_time = false
}
post-processor "shell-local" {
inline = ["echo $PACKER_BUILD_NAME >> build.txt"]
}
### clean up /home/packer ###
#provisioner "shell" {
# inline = [
# "sudo su root -c 'userdel -rf packer'"
# ]
#}
}