github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/aws/autoscaling.go (about) 1 // Copyright 2018 The Terraformer Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package aws 16 17 import ( 18 "context" 19 20 "github.com/GoogleCloudPlatform/terraformer/terraformutils" 21 22 "github.com/aws/aws-sdk-go-v2/service/autoscaling" 23 "github.com/aws/aws-sdk-go-v2/service/ec2" 24 25 "github.com/aws/aws-sdk-go-v2/aws" 26 ) 27 28 var AsgAllowEmptyValues = []string{"tags."} 29 30 type AutoScalingGenerator struct { 31 AWSService 32 } 33 34 func (g *AutoScalingGenerator) loadAutoScalingGroups(svc *autoscaling.Client) error { 35 p := autoscaling.NewDescribeAutoScalingGroupsPaginator(svc, &autoscaling.DescribeAutoScalingGroupsInput{}) 36 for p.HasMorePages() { 37 page, err := p.NextPage(context.TODO()) 38 if err != nil { 39 return err 40 } 41 for _, asg := range page.AutoScalingGroups { 42 resourceName := StringValue(asg.AutoScalingGroupName) 43 g.Resources = append(g.Resources, terraformutils.NewResource( 44 resourceName, 45 resourceName, 46 "aws_autoscaling_group", 47 "aws", 48 map[string]string{ 49 "force_delete": "false", 50 "metrics_granularity": "1Minute", 51 "wait_for_capacity_timeout": "10m", 52 }, 53 AsgAllowEmptyValues, 54 map[string]interface{}{}, 55 )) 56 } 57 } 58 return nil 59 } 60 61 func (g *AutoScalingGenerator) loadLaunchConfigurations(svc *autoscaling.Client) error { 62 p := autoscaling.NewDescribeLaunchConfigurationsPaginator(svc, &autoscaling.DescribeLaunchConfigurationsInput{}) 63 for p.HasMorePages() { 64 page, err := p.NextPage(context.TODO()) 65 if err != nil { 66 return err 67 } 68 for _, lc := range page.LaunchConfigurations { 69 resourceName := StringValue(lc.LaunchConfigurationName) 70 attributes := map[string]string{} 71 // only for LaunchConfigurations with userdata, we want get user_data_base64 72 if StringValue(lc.UserData) != "" { 73 attributes["user_data_base64"] = "=" // need set not empty string to get user_data_base64 from provider 74 } 75 g.Resources = append(g.Resources, terraformutils.NewResource( 76 resourceName, 77 resourceName, 78 "aws_launch_configuration", 79 "aws", 80 attributes, 81 AsgAllowEmptyValues, 82 map[string]interface{}{}, 83 )) 84 } 85 } 86 return nil 87 } 88 89 func (g *AutoScalingGenerator) loadLaunchTemplates(config aws.Config) error { 90 ec2svc := ec2.NewFromConfig(config) 91 92 p := ec2.NewDescribeLaunchTemplatesPaginator(ec2svc, &ec2.DescribeLaunchTemplatesInput{}) 93 for p.HasMorePages() { 94 page, err := p.NextPage(context.TODO()) 95 if err != nil { 96 return err 97 } 98 for _, lt := range page.LaunchTemplates { 99 g.Resources = append(g.Resources, terraformutils.NewSimpleResource( 100 StringValue(lt.LaunchTemplateId), 101 StringValue(lt.LaunchTemplateName), 102 "aws_launch_template", 103 "aws", 104 AsgAllowEmptyValues, 105 )) 106 } 107 } 108 return nil 109 } 110 111 // Generate TerraformResources from AWS API, 112 // from each ASG create 1 TerraformResource. 113 // Need only ASG name as ID for terraform resource 114 // AWS api support paging 115 func (g *AutoScalingGenerator) InitResources() error { 116 config, e := g.generateConfig() 117 if e != nil { 118 return e 119 } 120 svc := autoscaling.NewFromConfig(config) 121 if err := g.loadAutoScalingGroups(svc); err != nil { 122 return err 123 } 124 if err := g.loadLaunchConfigurations(svc); err != nil { 125 return err 126 } 127 if err := g.loadLaunchTemplates(config); err != nil { 128 return err 129 } 130 return nil 131 } 132 133 func (g *AutoScalingGenerator) PostConvertHook() error { 134 for i, r := range g.Resources { 135 if r.InstanceInfo.Type != "aws_autoscaling_group" { 136 continue 137 } 138 if lcName, exist := r.InstanceState.Attributes["launch_configuration"]; exist { 139 for _, lc := range g.Resources { 140 if lc.InstanceInfo.Type != "aws_launch_configuration" { 141 continue 142 } 143 if lcName == lc.InstanceState.Attributes["name"] { 144 g.Resources[i].Item["launch_configuration"] = "${aws_launch_configuration." + lc.ResourceName + ".name}" 145 continue 146 } 147 } 148 } 149 // TODO add LaunchTemplate and mix policy connection naming 150 } 151 // TODO fix tfVar value 152 /* 153 templateFiles := []terraformutils.Resource{} 154 for i, r := range g.Resources { 155 if r.InstanceInfo.Type != "aws_launch_configuration" { 156 continue 157 } 158 if userDataBase64, exist := r.InstanceState.Attributes["user_data_base64"]; exist { 159 userData, err := base64.StdEncoding.DecodeString(userDataBase64) 160 if err != nil { 161 continue 162 } 163 fileName := "userdata-" + r.ServiceName + ".txt" 164 err = ioutil.WriteFile(fileName, userData, os.ModePerm) // TODO write files in tf file path 165 if err != nil { 166 continue 167 } 168 userDataFile := terraformutils.NewResource( 169 r.ServiceName+"_userdata", 170 r.ServiceName+"_userdata", 171 "template_file", 172 "", 173 map[string]string{}, 174 []string{}, 175 map[string]string{}, 176 ) 177 tfVar := strings.Replace(fmt.Sprintf("${base64decode(file(\"%s\"))}", fileName), "\\\"", "\"", -1) 178 userDataFile.Item = map[string]interface{}{ 179 "template": tfVar, 180 } 181 182 delete(g.Resources[i].Item, "user_data_base64") 183 g.Resources[i].Item["user_data"] = "${template_file." + userDataFile.ServiceName + ".rendered}" 184 templateFiles = append(templateFiles, userDataFile) 185 } 186 } 187 g.Resources = append(g.Resources, templateFiles...) 188 */ 189 return nil 190 }