lib/terraforming/cli.rb
module Terraforming
class CLI < Thor
class_option :merge, type: :string, desc: "tfstate file to merge"
class_option :overwrite, type: :boolean, desc: "Overwrite existing tfstate"
class_option :tfstate, type: :boolean, desc: "Generate tfstate"
class_option :profile, type: :string, desc: "AWS credentials profile"
class_option :region, type: :string, desc: "AWS region"
class_option :assume, type: :string, desc: "Role ARN to assume"
class_option :use_bundled_cert,
type: :boolean,
desc: "Use the bundled CA certificate from AWS SDK"
desc "alb", "ALB"
def alb
execute(Terraforming::Resource::ALB, options)
end
desc "asg", "AutoScaling Group"
def asg
execute(Terraforming::Resource::AutoScalingGroup, options)
end
desc "cwa", "CloudWatch Alarm"
def cwa
execute(Terraforming::Resource::CloudWatchAlarm, options)
end
desc "dbpg", "Database Parameter Group"
def dbpg
execute(Terraforming::Resource::DBParameterGroup, options)
end
desc "dbsg", "Database Security Group"
def dbsg
execute(Terraforming::Resource::DBSecurityGroup, options)
end
desc "dbsn", "Database Subnet Group"
def dbsn
execute(Terraforming::Resource::DBSubnetGroup, options)
end
desc "ddb", "DynamoDB"
def ddb
execute(Terraforming::Resource::DynamoDB, options)
end
desc "ec2", "EC2"
def ec2
execute(Terraforming::Resource::EC2, options)
end
desc "ecc", "ElastiCache Cluster"
def ecc
execute(Terraforming::Resource::ElastiCacheCluster, options)
end
desc "ecsn", "ElastiCache Subnet Group"
def ecsn
execute(Terraforming::Resource::ElastiCacheSubnetGroup, options)
end
desc "eip", "EIP"
def eip
execute(Terraforming::Resource::EIP, options)
end
desc "efs", "EFS File System"
def efs
execute(Terraforming::Resource::EFSFileSystem, options)
end
desc "elb", "ELB"
def elb
execute(Terraforming::Resource::ELB, options)
end
desc "iamg", "IAM Group"
def iamg
execute(Terraforming::Resource::IAMGroup, options)
end
desc "iamgm", "IAM Group Membership"
def iamgm
execute(Terraforming::Resource::IAMGroupMembership, options)
end
desc "iamgp", "IAM Group Policy"
def iamgp
execute(Terraforming::Resource::IAMGroupPolicy, options)
end
desc "iamip", "IAM Instance Profile"
def iamip
execute(Terraforming::Resource::IAMInstanceProfile, options)
end
desc "iamp", "IAM Policy"
def iamp
execute(Terraforming::Resource::IAMPolicy, options)
end
desc "iampa", "IAM Policy Attachment"
def iampa
execute(Terraforming::Resource::IAMPolicyAttachment, options)
end
desc "iamr", "IAM Role"
def iamr
execute(Terraforming::Resource::IAMRole, options)
end
desc "iamrp", "IAM Role Policy"
def iamrp
execute(Terraforming::Resource::IAMRolePolicy, options)
end
desc "iamu", "IAM User"
def iamu
execute(Terraforming::Resource::IAMUser, options)
end
desc "iamup", "IAM User Policy"
def iamup
execute(Terraforming::Resource::IAMUserPolicy, options)
end
desc "kmsa", "KMS Key Alias"
def kmsa
execute(Terraforming::Resource::KMSAlias, options)
end
desc "kmsk", "KMS Key"
def kmsk
execute(Terraforming::Resource::KMSKey, options)
end
desc "lc", "Launch Configuration"
def lc
execute(Terraforming::Resource::LaunchConfiguration, options)
end
desc "igw", "Internet Gateway"
def igw
execute(Terraforming::Resource::InternetGateway, options)
end
desc "nacl", "Network ACL"
def nacl
execute(Terraforming::Resource::NetworkACL, options)
end
desc "nat", "NAT Gateway"
def nat
execute(Terraforming::Resource::NATGateway, options)
end
desc "nif", "Network Interface"
def nif
execute(Terraforming::Resource::NetworkInterface, options)
end
desc "r53r", "Route53 Record"
def r53r
execute(Terraforming::Resource::Route53Record, options)
end
desc "r53z", "Route53 Hosted Zone"
def r53z
execute(Terraforming::Resource::Route53Zone, options)
end
desc "rds", "RDS"
def rds
execute(Terraforming::Resource::RDS, options)
end
desc "rs", "Redshift"
def rs
execute(Terraforming::Resource::Redshift, options)
end
desc "rt", "Route Table"
def rt
execute(Terraforming::Resource::RouteTable, options)
end
desc "rta", "Route Table Association"
def rta
execute(Terraforming::Resource::RouteTableAssociation, options)
end
desc "s3", "S3"
def s3
execute(Terraforming::Resource::S3, options)
end
desc "sg", "Security Group"
def sg
execute(Terraforming::Resource::SecurityGroup, options)
end
desc "sn", "Subnet"
def sn
execute(Terraforming::Resource::Subnet, options)
end
desc "sqs", "SQS"
def sqs
execute(Terraforming::Resource::SQS, options)
end
desc "vpc", "VPC"
def vpc
execute(Terraforming::Resource::VPC, options)
end
desc "vgw", "VPN Gateway"
def vgw
execute(Terraforming::Resource::VPNGateway, options)
end
desc "snst", "SNS Topic"
def snst
execute(Terraforming::Resource::SNSTopic, options)
end
desc "snss", "SNS Subscription"
def snss
execute(Terraforming::Resource::SNSTopicSubscription, options)
end
private
def configure_aws(options)
Aws.config[:credentials] = Aws::SharedCredentials.new(profile_name: options[:profile]) if options[:profile]
Aws.config[:region] = options[:region] if options[:region]
if options[:assume]
args = { role_arn: options[:assume], role_session_name: "terraforming-session-#{Time.now.to_i}" }
args[:client] = Aws::STS::Client.new(profile: options[:profile]) if options[:profile]
Aws.config[:credentials] = Aws::AssumeRoleCredentials.new(args)
end
Aws.use_bundled_cert! if options[:use_bundled_cert]
end
def execute(klass, options)
configure_aws(options)
result = options[:tfstate] ? tfstate(klass, options[:merge]) : tf(klass)
if options[:tfstate] && options[:merge] && options[:overwrite]
open(options[:merge], "w+") do |f|
f.write(result)
f.flush
end
else
puts result
end
end
def tf(klass)
klass.tf
end
def tfstate(klass, tfstate_path)
tfstate = tfstate_path ? MultiJson.load(open(tfstate_path).read) : tfstate_skeleton
tfstate["serial"] = tfstate["serial"] + 1
tfstate["modules"][0]["resources"] = tfstate["modules"][0]["resources"].merge(klass.tfstate)
MultiJson.encode(tfstate, pretty: true)
end
def tfstate_skeleton
{
"version" => 1,
"serial" => 0,
"modules" => [
{
"path" => [
"root"
],
"outputs" => {},
"resources" => {},
}
]
}
end
end
end