From 8b20d419c0c5ad3fbf112d667476dad0155d0808 Mon Sep 17 00:00:00 2001 From: Oleksandr Kuzminskyi Date: Wed, 24 Jun 2026 15:57:30 -0700 Subject: [PATCH] Pin TF_PLUGIN_CACHE_DIR to a predictable path on terraformer (#274) Configure a shared Terraform provider plugin cache at a fixed path so provider binaries are stored once under a deterministic prefix instead of per-workdir .terraform/providers paths that vary run to run. This gives AWS Inspector EC2 scanning a single PREFIX anchor to suppress the provider-binary noise while still scanning the host's OS packages. New profile::terraformer::plugin_cache: - creates /var/cache/terraform/plugins (terraform won't create it itself) - exports TF_PLUGIN_CACHE_DIR via /etc/profile.d for login shells - makes the cache writable by the admin group (setgid + default POSIX ACL) so non-privileged admin users sharing the box can populate it Mirrored across the top-level, development, and sandbox module copies. Pairs with infrahouse/terraform-aws-terraformer#34. Co-Authored-By: Claude Opus 4.8 (1M context) --- debian/changelog | 6 +++ .../modules/profile/manifests/terraformer.pp | 3 ++ .../manifests/terraformer/plugin_cache.pp | 51 +++++++++++++++++++ .../modules/profile/manifests/terraformer.pp | 3 ++ .../manifests/terraformer/plugin_cache.pp | 51 +++++++++++++++++++ modules/profile/manifests/terraformer.pp | 3 ++ .../manifests/terraformer/plugin_cache.pp | 51 +++++++++++++++++++ 7 files changed, 168 insertions(+) create mode 100644 environments/development/modules/profile/manifests/terraformer/plugin_cache.pp create mode 100644 environments/sandbox/modules/profile/manifests/terraformer/plugin_cache.pp create mode 100644 modules/profile/manifests/terraformer/plugin_cache.pp diff --git a/debian/changelog b/debian/changelog index 8b80499..0afbc1b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +puppet-code (0.1.0-1build307) noble; urgency=medium + + * commit event. see changes history in git log + + -- root Wed, 24 Jun 2026 22:57:31 +0000 + puppet-code (0.1.0-1build306) noble; urgency=medium * commit event. see changes history in git log diff --git a/environments/development/modules/profile/manifests/terraformer.pp b/environments/development/modules/profile/manifests/terraformer.pp index ba36fc9..e9d4086 100644 --- a/environments/development/modules/profile/manifests/terraformer.pp +++ b/environments/development/modules/profile/manifests/terraformer.pp @@ -13,4 +13,7 @@ # CloudWatch agent for logging and metrics include profile::terraformer::cloudwatch_agent + + # Shared Terraform provider plugin cache at a predictable path + include profile::terraformer::plugin_cache } diff --git a/environments/development/modules/profile/manifests/terraformer/plugin_cache.pp b/environments/development/modules/profile/manifests/terraformer/plugin_cache.pp new file mode 100644 index 0000000..50397d9 --- /dev/null +++ b/environments/development/modules/profile/manifests/terraformer/plugin_cache.pp @@ -0,0 +1,51 @@ +# @summary: Shared, predictable Terraform provider plugin cache. +# +# Pins TF_PLUGIN_CACHE_DIR to a constant path so provider binaries are cached once +# under a deterministic prefix (instead of per-workdir .terraform/providers paths that +# vary run to run). This lets AWS Inspector EC2 scanning suppress the provider-binary +# noise with a single PREFIX filter while still scanning the host's OS packages. +# +# Terraform does not create the cache dir itself, so we create it here. +# See: https://developer.hashicorp.com/terraform/cli/config/config-file#provider-plugin-cache +class profile::terraformer::plugin_cache ( + String $cache_dir = '/var/cache/terraform/plugins', + String $cache_group = 'admin', +) { + # ACL tooling so the admin group can share the cache (see exec below). + stdlib::ensure_packages(['acl']) + + file { '/var/cache/terraform': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + # setgid so new entries inherit the admin group; the default ACL below adds the + # group-write that the umask would otherwise strip from nested dirs. + file { $cache_dir: + ensure => directory, + owner => 'root', + group => $cache_group, + mode => '2775', + require => File['/var/cache/terraform'], + } + + # Default + access ACL so every provider dir/file terraform creates stays writable + # by the admin group. Idempotent via the unless guard. + exec { 'terraformer-plugin-cache-acl': + command => "setfacl -R -m d:g:${cache_group}:rwx -m g:${cache_group}:rwx ${cache_dir}", + path => ['/usr/bin', '/bin'], + unless => "getfacl -pc ${cache_dir} | grep -qx 'default:group:${cache_group}:rwx'", + require => [Package['acl'], File[$cache_dir]], + } + + # Export the cache dir for interactive login shells; terraform reads this env var. + file { '/etc/profile.d/terraform-plugin-cache.sh': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + content => "# Managed by Puppet (profile::terraformer::plugin_cache)\nexport TF_PLUGIN_CACHE_DIR=${cache_dir}\n", + } +} diff --git a/environments/sandbox/modules/profile/manifests/terraformer.pp b/environments/sandbox/modules/profile/manifests/terraformer.pp index ba36fc9..e9d4086 100644 --- a/environments/sandbox/modules/profile/manifests/terraformer.pp +++ b/environments/sandbox/modules/profile/manifests/terraformer.pp @@ -13,4 +13,7 @@ # CloudWatch agent for logging and metrics include profile::terraformer::cloudwatch_agent + + # Shared Terraform provider plugin cache at a predictable path + include profile::terraformer::plugin_cache } diff --git a/environments/sandbox/modules/profile/manifests/terraformer/plugin_cache.pp b/environments/sandbox/modules/profile/manifests/terraformer/plugin_cache.pp new file mode 100644 index 0000000..50397d9 --- /dev/null +++ b/environments/sandbox/modules/profile/manifests/terraformer/plugin_cache.pp @@ -0,0 +1,51 @@ +# @summary: Shared, predictable Terraform provider plugin cache. +# +# Pins TF_PLUGIN_CACHE_DIR to a constant path so provider binaries are cached once +# under a deterministic prefix (instead of per-workdir .terraform/providers paths that +# vary run to run). This lets AWS Inspector EC2 scanning suppress the provider-binary +# noise with a single PREFIX filter while still scanning the host's OS packages. +# +# Terraform does not create the cache dir itself, so we create it here. +# See: https://developer.hashicorp.com/terraform/cli/config/config-file#provider-plugin-cache +class profile::terraformer::plugin_cache ( + String $cache_dir = '/var/cache/terraform/plugins', + String $cache_group = 'admin', +) { + # ACL tooling so the admin group can share the cache (see exec below). + stdlib::ensure_packages(['acl']) + + file { '/var/cache/terraform': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + # setgid so new entries inherit the admin group; the default ACL below adds the + # group-write that the umask would otherwise strip from nested dirs. + file { $cache_dir: + ensure => directory, + owner => 'root', + group => $cache_group, + mode => '2775', + require => File['/var/cache/terraform'], + } + + # Default + access ACL so every provider dir/file terraform creates stays writable + # by the admin group. Idempotent via the unless guard. + exec { 'terraformer-plugin-cache-acl': + command => "setfacl -R -m d:g:${cache_group}:rwx -m g:${cache_group}:rwx ${cache_dir}", + path => ['/usr/bin', '/bin'], + unless => "getfacl -pc ${cache_dir} | grep -qx 'default:group:${cache_group}:rwx'", + require => [Package['acl'], File[$cache_dir]], + } + + # Export the cache dir for interactive login shells; terraform reads this env var. + file { '/etc/profile.d/terraform-plugin-cache.sh': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + content => "# Managed by Puppet (profile::terraformer::plugin_cache)\nexport TF_PLUGIN_CACHE_DIR=${cache_dir}\n", + } +} diff --git a/modules/profile/manifests/terraformer.pp b/modules/profile/manifests/terraformer.pp index ba36fc9..e9d4086 100644 --- a/modules/profile/manifests/terraformer.pp +++ b/modules/profile/manifests/terraformer.pp @@ -13,4 +13,7 @@ # CloudWatch agent for logging and metrics include profile::terraformer::cloudwatch_agent + + # Shared Terraform provider plugin cache at a predictable path + include profile::terraformer::plugin_cache } diff --git a/modules/profile/manifests/terraformer/plugin_cache.pp b/modules/profile/manifests/terraformer/plugin_cache.pp new file mode 100644 index 0000000..50397d9 --- /dev/null +++ b/modules/profile/manifests/terraformer/plugin_cache.pp @@ -0,0 +1,51 @@ +# @summary: Shared, predictable Terraform provider plugin cache. +# +# Pins TF_PLUGIN_CACHE_DIR to a constant path so provider binaries are cached once +# under a deterministic prefix (instead of per-workdir .terraform/providers paths that +# vary run to run). This lets AWS Inspector EC2 scanning suppress the provider-binary +# noise with a single PREFIX filter while still scanning the host's OS packages. +# +# Terraform does not create the cache dir itself, so we create it here. +# See: https://developer.hashicorp.com/terraform/cli/config/config-file#provider-plugin-cache +class profile::terraformer::plugin_cache ( + String $cache_dir = '/var/cache/terraform/plugins', + String $cache_group = 'admin', +) { + # ACL tooling so the admin group can share the cache (see exec below). + stdlib::ensure_packages(['acl']) + + file { '/var/cache/terraform': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + # setgid so new entries inherit the admin group; the default ACL below adds the + # group-write that the umask would otherwise strip from nested dirs. + file { $cache_dir: + ensure => directory, + owner => 'root', + group => $cache_group, + mode => '2775', + require => File['/var/cache/terraform'], + } + + # Default + access ACL so every provider dir/file terraform creates stays writable + # by the admin group. Idempotent via the unless guard. + exec { 'terraformer-plugin-cache-acl': + command => "setfacl -R -m d:g:${cache_group}:rwx -m g:${cache_group}:rwx ${cache_dir}", + path => ['/usr/bin', '/bin'], + unless => "getfacl -pc ${cache_dir} | grep -qx 'default:group:${cache_group}:rwx'", + require => [Package['acl'], File[$cache_dir]], + } + + # Export the cache dir for interactive login shells; terraform reads this env var. + file { '/etc/profile.d/terraform-plugin-cache.sh': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + content => "# Managed by Puppet (profile::terraformer::plugin_cache)\nexport TF_PLUGIN_CACHE_DIR=${cache_dir}\n", + } +}