github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/aws/alb.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 "fmt" 20 "log" 21 22 "github.com/GoogleCloudPlatform/terraformer/terraformutils" 23 "github.com/aws/aws-sdk-go-v2/aws" 24 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" 25 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" 26 "github.com/hashicorp/terraform/helper/resource" 27 ) 28 29 var AlbAllowEmptyValues = []string{"tags.", "^condition."} 30 31 type AlbGenerator struct { 32 AWSService 33 } 34 35 func (g *AlbGenerator) loadLB(svc *elasticloadbalancingv2.Client) error { 36 p := elasticloadbalancingv2.NewDescribeLoadBalancersPaginator(svc, &elasticloadbalancingv2.DescribeLoadBalancersInput{}) 37 for p.HasMorePages() { 38 page, err := p.NextPage(context.TODO()) 39 if err != nil { 40 return err 41 } 42 for _, lb := range page.LoadBalancers { 43 resourceName := StringValue(lb.LoadBalancerName) 44 g.Resources = append(g.Resources, terraformutils.NewSimpleResource( 45 *lb.LoadBalancerArn, 46 resourceName, 47 "aws_lb", 48 "aws", 49 AlbAllowEmptyValues, 50 )) 51 err := g.loadLBListener(svc, lb.LoadBalancerArn) 52 if err != nil { 53 log.Println(err) 54 } 55 } 56 } 57 return nil 58 } 59 60 func (g *AlbGenerator) loadLBListener(svc *elasticloadbalancingv2.Client, loadBalancerArn *string) error { 61 p := elasticloadbalancingv2.NewDescribeListenersPaginator(svc, &elasticloadbalancingv2.DescribeListenersInput{LoadBalancerArn: loadBalancerArn}) 62 for p.HasMorePages() { 63 page, err := p.NextPage(context.TODO()) 64 if err != nil { 65 return err 66 } 67 for _, ls := range page.Listeners { 68 resourceName := *ls.ListenerArn 69 g.Resources = append(g.Resources, terraformutils.NewSimpleResource( 70 resourceName, 71 resourceName, 72 "aws_lb_listener", 73 "aws", 74 AlbAllowEmptyValues, 75 )) 76 err := g.loadLBListenerRule(svc, ls.ListenerArn) 77 if err != nil { 78 log.Println(err) 79 } 80 err = g.loadLBListenerCertificate(svc, &ls) 81 if err != nil { 82 log.Println(err) 83 } 84 } 85 } 86 return nil 87 } 88 89 func (g *AlbGenerator) loadLBListenerRule(svc *elasticloadbalancingv2.Client, listenerArn *string) error { 90 var marker *string 91 for { 92 lsrs, err := svc.DescribeRules(context.TODO(), &elasticloadbalancingv2.DescribeRulesInput{ 93 ListenerArn: listenerArn, 94 Marker: marker, 95 PageSize: aws.Int32(400)}, 96 ) 97 if err != nil { 98 return err 99 } 100 for _, lsr := range lsrs.Rules { 101 if !lsr.IsDefault { 102 resourceName := *lsr.RuleArn 103 g.Resources = append(g.Resources, terraformutils.NewSimpleResource( 104 resourceName, 105 resourceName, 106 "aws_lb_listener_rule", 107 "aws", 108 AlbAllowEmptyValues, 109 )) 110 } 111 } 112 marker = lsrs.NextMarker 113 if marker == nil { 114 break 115 } 116 } 117 return nil 118 } 119 120 func (g *AlbGenerator) loadLBListenerCertificate(svc *elasticloadbalancingv2.Client, loadBalancer *types.Listener) error { 121 lcs, err := svc.DescribeListenerCertificates(context.TODO(), &elasticloadbalancingv2.DescribeListenerCertificatesInput{ 122 ListenerArn: loadBalancer.ListenerArn, 123 }) 124 if err != nil { 125 return err 126 } 127 for _, lc := range lcs.Certificates { 128 certificateArn := *lc.CertificateArn 129 if certificateArn == *loadBalancer.Certificates[0].CertificateArn { // discard default certificate 130 continue 131 } 132 g.Resources = append(g.Resources, terraformutils.NewResource( 133 certificateArn, 134 certificateArn, 135 "aws_lb_listener_certificate", 136 "aws", 137 map[string]string{ 138 "listener_arn": *loadBalancer.ListenerArn, 139 "certificate_arn": certificateArn, 140 }, 141 AlbAllowEmptyValues, 142 map[string]interface{}{}, 143 )) 144 } 145 return err 146 } 147 148 func (g *AlbGenerator) loadLBTargetGroup(svc *elasticloadbalancingv2.Client) error { 149 p := elasticloadbalancingv2.NewDescribeTargetGroupsPaginator(svc, &elasticloadbalancingv2.DescribeTargetGroupsInput{}) 150 for p.HasMorePages() { 151 page, err := p.NextPage(context.TODO()) 152 if err != nil { 153 return err 154 } 155 for _, tg := range page.TargetGroups { 156 resourceName := StringValue(tg.TargetGroupName) 157 g.Resources = append(g.Resources, terraformutils.NewSimpleResource( 158 *tg.TargetGroupArn, 159 resourceName, 160 "aws_lb_target_group", 161 "aws", 162 AlbAllowEmptyValues, 163 )) 164 err := g.loadTargetGroupTargets(svc, tg.TargetGroupArn) 165 if err != nil { 166 log.Println(err) 167 } 168 } 169 } 170 return nil 171 } 172 173 func (g *AlbGenerator) loadTargetGroupTargets(svc *elasticloadbalancingv2.Client, targetGroupArn *string) error { 174 targetHealths, err := svc.DescribeTargetHealth(context.TODO(), &elasticloadbalancingv2.DescribeTargetHealthInput{ 175 TargetGroupArn: targetGroupArn, 176 }) 177 if err != nil { 178 return err 179 } 180 for _, tgh := range targetHealths.TargetHealthDescriptions { 181 id := resource.PrefixedUniqueId(fmt.Sprintf("%s-", *targetGroupArn)) 182 g.Resources = append(g.Resources, terraformutils.NewResource( 183 id, 184 id, 185 "aws_lb_target_group_attachment", 186 "aws", 187 map[string]string{ 188 "target_id": *tgh.Target.Id, 189 "target_group_arn": *targetGroupArn, 190 }, 191 AlbAllowEmptyValues, 192 map[string]interface{}{}, 193 )) 194 } 195 return nil 196 } 197 198 // Generate TerraformResources from AWS API, 199 func (g *AlbGenerator) InitResources() error { 200 config, e := g.generateConfig() 201 if e != nil { 202 return e 203 } 204 svc := elasticloadbalancingv2.NewFromConfig(config) 205 if err := g.loadLB(svc); err != nil { 206 return err 207 } 208 if err := g.loadLBTargetGroup(svc); err != nil { 209 return err 210 } 211 return nil 212 } 213 214 func (g *AlbGenerator) PostConvertHook() error { 215 for _, r := range g.Resources { 216 if r.InstanceInfo.Type != "aws_lb_listener" { 217 continue 218 } 219 if r.InstanceState.Attributes["default_action.0.order"] == "0" { 220 delete(r.Item["default_action"].([]interface{})[0].(map[string]interface{}), "order") 221 } 222 } 223 224 for i, r := range g.Resources { 225 if r.InstanceInfo.Type != "aws_lb_listener_rule" { 226 continue 227 } 228 if r.InstanceState.Attributes["action.0.order"] == "0" { 229 delete(r.Item["action"].([]interface{})[0].(map[string]interface{}), "order") 230 } 231 for _, lb := range g.Resources { 232 if lb.InstanceInfo.Type != "aws_lb_listener_certificate" { 233 continue 234 } 235 if r.InstanceState.Attributes["certificate_arn"] == lb.InstanceState.Attributes["arn"] { 236 g.Resources[i].Item["certificate_arn"] = "${aws_lb_listener_certificate." + lb.ResourceName + ".arn}" 237 } 238 } 239 } 240 241 for _, r := range g.Resources { 242 if r.InstanceInfo.Type != "aws_lb" { 243 continue 244 } 245 if val, ok := r.InstanceState.Attributes["access_logs.0.enabled"]; ok && val == "false" { 246 delete(r.Item, "access_logs") 247 } 248 } 249 return nil 250 }