Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Deferred functions / lookups for sensitive parameters #883

Open
arusso opened this issue Aug 29, 2023 · 0 comments
Open

Support for Deferred functions / lookups for sensitive parameters #883

arusso opened this issue Aug 29, 2023 · 0 comments

Comments

@arusso
Copy link

arusso commented Aug 29, 2023

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 7.25.0
  • Ruby: 2.7.8p225
  • Distribution: RHEL / AlmaLinux 9
  • Module version: 9.2.0

How to reproduce (e.g Puppet code you use)

$secret = Deferred('vault::vault_lookup', ["kv/data/hostgroup/zabbix/dev/db/role/zabbix", "vault.example.com"])
$database_pass = Deferred('inline_epp', ['<%= $secret.unwrap[data][password] %>', { 'secret' => $secret }])

class { 'zabbix::server':
   database_type     => postgresql,
   database_host     => 'zabbix-dev-db.example.com',
   database_name     => 'zabbix',
   database_user     => 'zabbix',
   database_password => $database_pass,
   manage_firewall   => false,
   manage_selinux    => false,
   manage_repo       => false,
   zabbix_version    => '6.4',
}

What are you seeing

Errors adding .pgpass line:

Notice: /Stage[main]/Zabbix::Database::Postgresql/Exec[update_pgpass]/returns: sh: -c: line 1: syntax error near unexpected token `('
Notice: /Stage[main]/Zabbix::Database::Postgresql/Exec[update_pgpass]/returns: sh: -c: line 1: `echo zabbix-dev-db.example.com:5432:zabbix:zabbix:Deferred({'name' => 'inline_epp', 'arguments' => ['<%= $secret.unwrap[data][$key] %>', {'secret' => Deferred({'name' => 'vault_lookup::lookup', 'arguments' => ['kv/data/hostgroup/app/zabbix/dev/db/roles/zabbix', 'https://vault.example.com']}), 'key' => 'password'}]}) >> /root/.pgpass'
Error: 'echo zabbix-dev-db.example.com:5432:zabbix:zabbix:Deferred({'name' => 'inline_epp', 'arguments' => ['<%= $secret.unwrap[data][$key] %>', {'secret' => Deferred({'name' => 'vault_lookup::lookup', 'arguments' => ['kv/data/hostgroup/app/zabbix/dev/db/roles/zabbix', 'https://vault.example.com']}), 'key' => 'password'}]}) >> /root/.pgpass' returned 2 instead of one of [0]
Error: /Stage[main]/Zabbix::Database::Postgresql/Exec[update_pgpass]/returns: change from 'notrun' to ['0'] failed: 'echo zabbix-dev-db.example.com:5432:zabbix:zabbix:Deferred({'name' => 'inline_epp', 'arguments' => ['<%= $secret.unwrap[data][$key] %>', {'secret' => Deferred({'name' => 'vault_lookup::lookup', 'arguments' => ['kv/data/hostgroup/app/zabbix/dev/db/roles/zabbix', 'https://vault.example.com']}), 'key' => 'password'}]}) >> /root/.pgpass' returned 2 instead of one of [0] (corrective)

And the server config has the serialized Deferred function rather than the secret:

DBPassword=Deferred({'name' => 'inline_epp', 'arguments' => ['<%= $secret.unwrap[data][$key] %>', {'secret' => Deferred({'name' => 'vault_lookup::lookup', 'arguments' => ['kv/data/hostgroup/app/zabbix/dev/db/roles/zabbix', 'https://vault.example.com']}), 'key' => 'password'}]})

What behaviour did you expect instead

The secrets from Vault to be rendered in the .pgpass and zabbix_server configuration.

Output log

Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for zabbix-dev-app-01.example.com
Info: Applying configuration version 'puppet-prod-srv-01-zabbix_app-47443a28e80'
Notice: /Stage[main]/Zabbix::Database::Postgresql/Exec[update_pgpass]/returns: sh: -c: line 1: syntax error near unexpected token `('
Notice: /Stage[main]/Zabbix::Database::Postgresql/Exec[update_pgpass]/returns: sh: -c: line 1: `echo zabbix-dev-db.example.com:5432:zabbix:zabbix:Deferred({'name' => 'inline_epp', 'arguments' => ['<%= $secret.unwrap[data][$key] %>', {'secret' => Deferred({'name' => 'vault_lookup::lookup', 'arguments' => ['kv/data/hostgroup/app/zabbix/dev/db/roles/zabbix', 'https://vault.example.com']}), 'key' => 'password'}]}) >> /root/.pgpass'
Error: 'echo zabbix-dev-db.example.com:5432:zabbix:zabbix:Deferred({'name' => 'inline_epp', 'arguments' => ['<%= $secret.unwrap[data][$key] %>', {'secret' => Deferred({'name' => 'vault_lookup::lookup', 'arguments' => ['kv/data/hostgroup/app/zabbix/dev/db/roles/zabbix', 'https://vault.example.com']}), 'key' => 'password'}]}) >> /root/.pgpass' returned 2 instead of one of [0]
Error: /Stage[main]/Zabbix::Database::Postgresql/Exec[update_pgpass]/returns: change from 'notrun' to ['0'] failed: 'echo zabbix-dev-db.example.com:5432:zabbix:zabbix:Deferred({'name' => 'inline_epp', 'arguments' => ['<%= $secret.unwrap[data][$key] %>', {'secret' => Deferred({'name' => 'vault_lookup::lookup', 'arguments' => ['kv/data/hostgroup/app/zabbix/dev/db/roles/zabbix', 'https://vault.example.com']}), 'key' => 'password'}]}) >> /root/.pgpass' returned 2 instead of one of [0] (corrective)
Notice: /Stage[main]/Zabbix::Database::Postgresql/Exec[zabbix_server_create.sql]: Dependency Exec[update_pgpass] has failures: true
Warning: /Stage[main]/Zabbix::Database::Postgresql/Exec[zabbix_server_create.sql]: Skipping because of failed dependencies
Warning: /Stage[main]/Zabbix::Database::Postgresql/Exec[zabbix_server_images.sql]: Skipping because of failed dependencies
Warning: /Stage[main]/Zabbix::Database::Postgresql/Exec[zabbix_server_data.sql]: Skipping because of failed dependencies
Notice: /Stage[main]/Zabbix::Server/File[/etc/zabbix/zabbix_server.conf]/content:
--- /etc/zabbix/zabbix_server.conf      2023-08-24 08:41:24.706462683 -0700
+++ /tmp/puppet-file20230829-17166-pkf6lx       2023-08-29 10:44:32.803339337 -0700
@@ -81,7 +81,7 @@
 #      Database password. Ignored for SQLite.
 #      Comment this line if no password is used.
 #
-DBPassword=zabbix_server
+DBPassword=Deferred({'name' => 'inline_epp', 'arguments' => ['<%= $secret.unwrap[data][$key] %>', {'secret' => Deferred({'name' => 'vault_lookup::lookup', 'arguments' => ['kv/data/hostgroup/app/zabbix/dev/db/roles/zabbix', 'https://vault.example.com']}), 'key' => 'password'}]})

 ### Option: DBSocket
 #      Path to MySQL socket.

Info: Computing checksum on file /etc/zabbix/zabbix_server.conf
Info: /Stage[main]/Zabbix::Server/File[/etc/zabbix/zabbix_server.conf]: Filebucketed /etc/zabbix/zabbix_server.conf to main with sum 331e233e911fa1ed7013e7524ce5ec221a8adaad700aec13aff996f3badfeeae
Notice: /Stage[main]/Zabbix::Server/File[/etc/zabbix/zabbix_server.conf]/content: content changed '{sha256}331e233e911fa1ed7013e7524ce5ec221a8adaad700aec13aff996f3badfeeae' to '{sha256}af9aab4ccec8dde24ed7e7a4b36f33f6fe142a58c2461e4a9dc227ebb770f304'
Info: /Stage[main]/Zabbix::Server/File[/etc/zabbix/zabbix_server.conf]: Scheduling refresh of Service[zabbix-server]
Notice: /Stage[main]/Zabbix::Server/Service[zabbix-server]: Triggered 'refresh' from 1 event
Info: Stage[main]: Unscheduling all events on Stage[main]
Notice: Applied catalog in 1.53 seconds
[root@zabbix-dev-app-01 ~]# puppet agent -t  --environment zabbix_app
Info: Using environment 'zabbix_app'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Error: Failed to apply catalog: Evaluation Error: A substring operation does not accept a String as a character index. Expected an Integer (file: inlined-epp-text, line: 1, column: 27)
[root@zabbix-dev-app-01 ~]# cd /root/
[root@zabbix-dev-app-01 ~]# cat .pgpass
zabbix-dev-db.example.com:5432:zabbix:zabbix:zabbix_server
[root@zabbix-dev-app-01 ~]# grep DBPassword /etc/zabbix/zabbix_server.conf
#       For SQLite3 path to database file must be provided. DBUser and DBPassword are ignored.
### Option: DBPassword
DBPassword=Deferred({'name' => 'inline_epp', 'arguments' => ['<%= $secret.unwrap[data][$key] %>', {'secret' => Deferred({'name' => 'vault_lookup::lookup', 'arguments' => ['kv/data/hostgroup/app/zabbix/dev/db/roles/zabbix', 'https://vault.example.com']}), 'key' => 'password'}]})

Any additional information you'd like to impart

It might be useful to also support Deferred values for database host, username, and db name so we can store the entire connection details alongside the password and change them atomically versus updating the password in one place and then also needing to update the connection details in hiera.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant