0

Facter contains GCE (Google Compute Engine) metadata details:

$ facter | grep gce
gce => {"instance"=>{"attributes"=>{}, "description"=>"", "disks"=>[{"deviceName"=>"srvpup01", "index"=>0, "mode"=>"READ_WRITE", "type"=>"PERSISTENT"}, {"deviceName"=>"srvpup01-storage01", "index"=>1, "mode"=>"READ_WRITE", "type"=>"PERSISTENT"}], "hostname"=>"srvpup01.c.example.internal", "id"=>12345, "image"=>nil, "licenses"=>[{"id"=>"1000010"}], "machineType"=>"n1-standard-1", "maintenanceEvent"=>"NONE", "networkInterfaces"=>[{"accessConfigs"=>[{"externalIp"=>"", "type"=>"ONE_TO_ONE_NAT"}], "forwardedIps"=>[], "ip"=>"123.456.789.123", "ipAliases"=>[], "mac"=>"00:11:22:33:44:55", "network"=>"example"}], "scheduling"=>{"automaticRestart"=>"TRUE", "onHostMaintenance"=>"MIGRATE", "preemptible"=>"FALSE"}, "serviceAccounts"=>{"12345-compute@developer.gserviceaccount.com"=>{"aliases"=>["default"], "email"=>"12345-compute@developer.gserviceaccount.com", "scopes"=>["xxx"]}, "default"=>{"aliases"=>["default"], "email"=>"12345-compute@developer.gserviceaccount.com", "scopes"=>["xxx"]}}, "tags"=>["no-public-ip"], "zone"=>"europe-west1-d"}, "project"=>{"attributes"=>{"google-compute-default-region"=>"europe-west1", "google-compute-default-zone"=>"europe-west1-d", "sshKeys"=>["...

Is there any easy way accessing like for example the "zone" attribute from within a puppet module or do I have to parse that string by myself?

Accessing it like a hash fails:

gce is not a hash or array

2 Answers2

1

The error gce is not a hash or array suggests you're on Puppet 3.x (rather than 4.x) which treats all facts as strings, so to access the value inside the hash you will need to turn off the stringify_facts setting.

This can be done in puppet.conf on all of your agents with:

stringify_facts = false

You should then be able to access the value using:

$gce["zone"]
Dominic Cleal
  • 3,160
  • 19
  • 16
0

I don't think the facter command line can print out the value of a nested fact like gce.zone, so you probably will need to parse it.

Note a couple of things:

  1. You can pass the name of the top-level fact on the command line so it only prints that out: facter gce will print just the hash without the "gce =>" prefix, or need to grep.
  2. You can output the fact in JSON or YAML formats to make it easier to parse.

Using jgrep you could do:

facter --json gce | jgrep -s gce.zone

or using YAML and Ruby you could do:

facter --yaml gce | ruby -ryaml -e 'p YAML.load(STDIN)["gce"]["zone"]'

or using YAML and awk:

facter --yaml gce | awk '/zone:/ { print $2 }'
Dominic Cleal
  • 3,160
  • 19
  • 16
  • OK sorry, I didn't phrase my question specific enough. That facter output was just to visualize the structure of that fact. Instead of command line, I'm trying to access that fact from within a Puppet module, but whatever I do, it either just returns the whole gce structure or exits with "gce is not a hash or array" – user1737246 Jul 27 '16 at 10:31
  • Ah, I posted another answer about Puppet (3.x I presume). – Dominic Cleal Jul 27 '16 at 13:39