diff --git a/common/configuration/puppet.yaml.tftpl b/common/configuration/puppet.yaml.tftpl index a4432019..dc2337e0 100644 --- a/common/configuration/puppet.yaml.tftpl +++ b/common/configuration/puppet.yaml.tftpl @@ -107,6 +107,10 @@ runcmd: - chmod 0640 /etc/puppetlabs/puppet/eyaml/boot_private_key.pkcs7.pem # Setup puppet environment code and modules - rm -rf /etc/puppetlabs/code/environments/production +%{ if cloud_provider == "incus" && startswith(puppetenv_git, "file://") ~} + # Incus mounts can have host ownership; allow git to read the repo safely. + - git config --system --add safe.directory /opt/magic-castle/puppetenv/.git +%{ endif ~} - git clone ${puppetenv_git} /etc/puppetlabs/code/environments/main - ln -s /etc/puppetlabs/code/environments/main /etc/puppetlabs/code/environments/production - | diff --git a/common/variables.tf b/common/variables.tf index 07091ac2..0f58897b 100644 --- a/common/variables.tf +++ b/common/variables.tf @@ -74,8 +74,8 @@ variable "config_git_url" { type = string description = "URL to the Magic Castle Puppet configuration git repo" validation { - condition = can(regex("^https://.*\\.git$", var.config_git_url)) - error_message = "The config_git_url variable must be an https url to a git repo." + condition = can(regex("^(https://.*\\.git|/.*|file:///.+)$", var.config_git_url)) + error_message = "The config_git_url variable must be an https url to a git repo or an absolute local path (optionally prefixed with file://)." } } diff --git a/docs/README.md b/docs/README.md index efacfd19..5bf70da1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -328,6 +328,11 @@ config_git_url = "https://oauth2:${oauth-key-goes-here}@domain.com/username/repo ``` This works for GitHub and GitLab (including community edition). +For the `incus` provider only, `config_git_url` can also be an absolute local +path (or `file:///...`) to a git repository on the host running Incus. The +repository is mounted into the puppet server at `/opt/magic-castle/puppetenv` +and cloned via `file:///opt/magic-castle/puppetenv`. + **Post build modification effect**: no effect. To change the Puppet configuration source, destroy the cluster or change it manually on the Puppet server. diff --git a/incus/infrastructure.tf b/incus/infrastructure.tf index 2a96eb99..06ee09bb 100644 --- a/incus/infrastructure.tf +++ b/incus/infrastructure.tf @@ -11,11 +11,18 @@ module "design" { bastion_tags = var.bastion_tags } +locals { + config_git_url_is_local = can(regex("^(file://|/)", var.config_git_url)) + config_git_url_host_path = local.config_git_url_is_local ? replace(var.config_git_url, "file://", "") : null + config_git_url_mount_path = local.config_git_url_is_local ? "/opt/magic-castle/puppetenv" : null + config_git_url_effective = local.config_git_url_is_local ? "file://${local.config_git_url_mount_path}" : var.config_git_url +} + module "configuration" { source = "../common/configuration" inventory = local.inventory post_inventory = local.post_inventory - config_git_url = var.config_git_url + config_git_url = local.config_git_url_effective config_version = var.config_version sudoer_username = var.sudoer_username public_keys = var.public_keys @@ -115,6 +122,19 @@ resource "incus_instance" "instances" { } } + dynamic "device" { + for_each = contains(each.value.tags, "puppet") && local.config_git_url_is_local ? { puppetenv = local.config_git_url_host_path } : {} + content { + type = "disk" + name = "puppetenv" + properties = { + source = device.value + path = local.config_git_url_mount_path + readonly = true + } + } + } + dynamic "device" { for_each = incus_storage_volume.filesystems content {