#
# Query AWS for all Exports, Outputs, Parameters, Resources and Tags associated
# with the named stack and insert them into Facter as facts.
#
# Examples are plentiful for loading Tags into Facter; we load all the metadata
# related to the stack and its resources. Optional prefixes for different
# metadata types are set below. Use the empty string to remove the prefix.
#
# Requires: aws-sdk version 2
# Expects: 'stack_name' to be defined in Facter
require 'facter'
require 'open-uri'
require 'aws-sdk-core'
# Set a prefix for different types of metadata.
prefix = 'cf_'
prefix_export = 'cf__export_'
prefix_resource = 'cf__res_'
def aws_metadata(path)
return open("http://169.254.169.254/latest/meta-data/#{path}").read.split("\n")[0]
end
begin
Aws.config[:region] = aws_metadata('placement/availability-zone')[0..-2]
Aws.config[:credentials] = Aws::InstanceProfileCredentials.new
cloudformation = Aws::CloudFormation::Client.new
rescue Exception => e
p "Failed to query CloudFormation metadata."
p e
end
stack_id = Facter.value(:stack_name)
# Stack Outputs
begin
cloudformation.list_exports().each do |resp|
resp[:exports].each do |export|
Facter.add("#{prefix_export}#{export.name}") do
setcode do
export.value
end
end
end
end
rescue Exception => e
p "Unable to parse AWS CloudFormation Exports."
p e
end
# Stack Metadata
options = {stack_name: stack_id}
begin
cloudformation.describe_stacks(options).each do |resp|
resp[:stacks][0][:parameters].each do |param|
Facter.add("#{prefix}#{param.parameter_key}") do
setcode do
param.parameter_value
end
end
end
resp[:stacks][0][:outputs].each do |output|
Facter.add("#{prefix}#{output.output_key}") do
setcode do
output.output_value
end
end
end
resp[:stacks][0][:tags].each do |tag|
Facter.add("#{prefix}#{tag.key}") do
setcode do
tag.value
end
end
end
Facter.add("#{prefix}stack_id") { setcode { resp[:stacks][0][:stack_id] } }
Facter.add("#{prefix}stack_name") { setcode { resp[:stacks][0][:stack_name] } }
Facter.add("#{prefix}description") { setcode { resp[:stacks][0][:description] } }
end
rescue Exception => e
p "Unable to parse AWS CloudFormation Parameters."
p e
end
begin
cloudformation.describe_stack_resources(options).each do |resp|
resp[:stack_resources].each do |res|
Facter.add("#{prefix_resource}#{res.logical_resource_id}") do
setcode do
res.physical_resource_id
end
end
end
end
rescue Exception => e
p "Unable to parse AWS CloudFormation Resources."
p e
end