Skip to content

Instantly share code, notes, and snippets.

@buildkite-elastic-stack-releaser
Last active November 22, 2021 03:24
Show Gist options
  • Save buildkite-elastic-stack-releaser/6e5a51eaed8e6be2602cefe1eb3285fc to your computer and use it in GitHub Desktop.
Save buildkite-elastic-stack-releaser/6e5a51eaed8e6be2602cefe1eb3285fc to your computer and use it in GitHub Desktop.
Generate a terraform module for an Elastic CI Stack for AWS CloudFormation Template
#!/usr/bin/env ruby
file = ARGV[0]
if file.nil?
raise "Provide a path to a CloudFormation template"
end
$stderr.puts "Converting #{file}"
contents = File.read(file)
require 'yaml'
require 'json'
yaml = YAML.load(contents)
variables = []
parameters = yaml["Parameters"]
parameters.each_pair do |name, parameter|
properties = {}
if description = parameter["Description"]
properties["description"] = description
end
type = parameter["Type"]
if !type.nil?
properties["type"] = case type
when "String"
"string"
when "Number"
"number"
when "CommaDelimitedList"
"list(string)"
else
raise "Unsupported type `#{type}`"
end
end
if default = parameter["Default"]
properties["default"] = case type
when "CommaDelimitedList"
default.split(",")
else
default
end
end
condition_strings = []
error_strings = []
if allowedValues = parameter["AllowedValues"]
condition_strings << "contains(#{allowedValues.to_json}, var.#{name})"
error_strings << "#{name} must be one of #{allowedValues.join(', ')}."
end
if allowedPattern = parameter["AllowedPattern"]
condition_strings << "can(regex(#{allowedPattern.to_json}, var.#{name}))"
error_strings << "#{name} must match the regex \"#{allowedPattern}\"."
end
if minLength = parameter["MinLength"]
condition_strings << "length(var.#{name}) >= #{minLength}"
error_strings << "#{name} must have a length of at least #{minLength}."
end
if minValue = parameter["MinValue"]
condition_strings << "var.#{name} >= #{minValue}"
error_strings << "#{name} must have a value of at least #{minValue}."
end
if maxValue = parameter["MaxValue"]
condition_strings << "var.#{name} <= #{maxValue}"
error_strings << "#{name} must have a value of no more than #{maxValue}."
end
if constraintDescription = parameter["ConstraintDescription"]
error_strings << "#{name} #{constraintDescription}"
end
if condition_strings.size > 0
error_message = error_strings.join(' ')
if error_message[-1] != "."
error_message << "."
end
properties["validation"] = [
{
"condition" => "${#{condition_strings.join(' && ')}}",
"error_message" => error_message,
}
]
end
if noEcho = parameter["NoEcho"]
properties["sensitive"] = true
end
variable = {
name => [ properties ],
}
variables << variable
end
variables << {
"StackName" => [
{
"type" => "string",
"description" => "CloudFormation Stack Name",
"default" => "buildkite"
}
]
}
variables_by_parameters = {}
parameters.each_pair do |name, parameter|
variables_by_parameters[name] = case parameter["Type"]
when "CommaDelimitedList"
"${join(\",\", var.#{name})}"
else
"${var.#{name}}"
end
end
hcl = {
"variable" => variables,
"resource" => [
{
"aws_cloudformation_stack" => [
{
"elastic-ci-stack-for-aws": [
{
"capabilities": [
"CAPABILITY_NAMED_IAM",
"CAPABILITY_AUTO_EXPAND"
],
"name": "${var.StackName}",
# TODO make dynamic based on which template we are translating
"template_url": "https://s3.amazonaws.com/buildkite-aws-stack/latest/aws-stack.yml",
"parameters": variables_by_parameters
}
]
}
]
}
]
}
puts JSON.pretty_generate(hcl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment