providers/aws/autoscaling.go (120 lines of code) (raw):

// Copyright 2018 The Terraformer Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package aws import ( "context" "github.com/GoogleCloudPlatform/terraformer/terraformutils" "github.com/aws/aws-sdk-go-v2/service/autoscaling" "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/aws" ) var AsgAllowEmptyValues = []string{"tags."} type AutoScalingGenerator struct { AWSService } func (g *AutoScalingGenerator) loadAutoScalingGroups(svc *autoscaling.Client) error { p := autoscaling.NewDescribeAutoScalingGroupsPaginator(svc, &autoscaling.DescribeAutoScalingGroupsInput{}) for p.HasMorePages() { page, err := p.NextPage(context.TODO()) if err != nil { return err } for _, asg := range page.AutoScalingGroups { resourceName := StringValue(asg.AutoScalingGroupName) g.Resources = append(g.Resources, terraformutils.NewResource( resourceName, resourceName, "aws_autoscaling_group", "aws", map[string]string{ "force_delete": "false", "metrics_granularity": "1Minute", "wait_for_capacity_timeout": "10m", }, AsgAllowEmptyValues, map[string]interface{}{}, )) } } return nil } func (g *AutoScalingGenerator) loadLaunchConfigurations(svc *autoscaling.Client) error { p := autoscaling.NewDescribeLaunchConfigurationsPaginator(svc, &autoscaling.DescribeLaunchConfigurationsInput{}) for p.HasMorePages() { page, err := p.NextPage(context.TODO()) if err != nil { return err } for _, lc := range page.LaunchConfigurations { resourceName := StringValue(lc.LaunchConfigurationName) attributes := map[string]string{} // only for LaunchConfigurations with userdata, we want get user_data_base64 if StringValue(lc.UserData) != "" { attributes["user_data_base64"] = "=" // need set not empty string to get user_data_base64 from provider } g.Resources = append(g.Resources, terraformutils.NewResource( resourceName, resourceName, "aws_launch_configuration", "aws", attributes, AsgAllowEmptyValues, map[string]interface{}{}, )) } } return nil } func (g *AutoScalingGenerator) loadLaunchTemplates(config aws.Config) error { ec2svc := ec2.NewFromConfig(config) p := ec2.NewDescribeLaunchTemplatesPaginator(ec2svc, &ec2.DescribeLaunchTemplatesInput{}) for p.HasMorePages() { page, err := p.NextPage(context.TODO()) if err != nil { return err } for _, lt := range page.LaunchTemplates { g.Resources = append(g.Resources, terraformutils.NewSimpleResource( StringValue(lt.LaunchTemplateId), StringValue(lt.LaunchTemplateName), "aws_launch_template", "aws", AsgAllowEmptyValues, )) } } return nil } // Generate TerraformResources from AWS API, // from each ASG create 1 TerraformResource. // Need only ASG name as ID for terraform resource // AWS api support paging func (g *AutoScalingGenerator) InitResources() error { config, e := g.generateConfig() if e != nil { return e } svc := autoscaling.NewFromConfig(config) if err := g.loadAutoScalingGroups(svc); err != nil { return err } if err := g.loadLaunchConfigurations(svc); err != nil { return err } if err := g.loadLaunchTemplates(config); err != nil { return err } return nil } func (g *AutoScalingGenerator) PostConvertHook() error { for i, r := range g.Resources { if r.InstanceInfo.Type != "aws_autoscaling_group" { continue } if lcName, exist := r.InstanceState.Attributes["launch_configuration"]; exist { for _, lc := range g.Resources { if lc.InstanceInfo.Type != "aws_launch_configuration" { continue } if lcName == lc.InstanceState.Attributes["name"] { g.Resources[i].Item["launch_configuration"] = "${aws_launch_configuration." + lc.ResourceName + ".name}" continue } } } // TODO add LaunchTemplate and mix policy connection naming } // TODO fix tfVar value /* templateFiles := []terraformutils.Resource{} for i, r := range g.Resources { if r.InstanceInfo.Type != "aws_launch_configuration" { continue } if userDataBase64, exist := r.InstanceState.Attributes["user_data_base64"]; exist { userData, err := base64.StdEncoding.DecodeString(userDataBase64) if err != nil { continue } fileName := "userdata-" + r.ServiceName + ".txt" err = ioutil.WriteFile(fileName, userData, os.ModePerm) // TODO write files in tf file path if err != nil { continue } userDataFile := terraformutils.NewResource( r.ServiceName+"_userdata", r.ServiceName+"_userdata", "template_file", "", map[string]string{}, []string{}, map[string]string{}, ) tfVar := strings.Replace(fmt.Sprintf("${base64decode(file(\"%s\"))}", fileName), "\\\"", "\"", -1) userDataFile.Item = map[string]interface{}{ "template": tfVar, } delete(g.Resources[i].Item, "user_data_base64") g.Resources[i].Item["user_data"] = "${template_file." + userDataFile.ServiceName + ".rendered}" templateFiles = append(templateFiles, userDataFile) } } g.Resources = append(g.Resources, templateFiles...) */ return nil }