github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/aws/ecs.go (about)

     1  // Copyright 2019 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  	"strconv"
    21  	"strings"
    22  
    23  	"github.com/GoogleCloudPlatform/terraformer/terraformutils"
    24  	"github.com/aws/aws-sdk-go-v2/service/ecs"
    25  )
    26  
    27  var ecsAllowEmptyValues = []string{"tags."}
    28  
    29  type EcsGenerator struct {
    30  	AWSService
    31  }
    32  
    33  func (g *EcsGenerator) InitResources() error {
    34  	config, e := g.generateConfig()
    35  	if e != nil {
    36  		return e
    37  	}
    38  	svc := ecs.NewFromConfig(config)
    39  
    40  	p := ecs.NewListClustersPaginator(svc, &ecs.ListClustersInput{})
    41  	for p.HasMorePages() {
    42  		page, e := p.NextPage(context.TODO())
    43  		if e != nil {
    44  			return e
    45  		}
    46  		for _, clusterArn := range page.ClusterArns {
    47  			arnParts := strings.Split(clusterArn, "/")
    48  			clusterName := arnParts[len(arnParts)-1]
    49  
    50  			g.Resources = append(g.Resources, terraformutils.NewSimpleResource(
    51  				clusterArn,
    52  				clusterName,
    53  				"aws_ecs_cluster",
    54  				"aws",
    55  				ecsAllowEmptyValues,
    56  			))
    57  
    58  			servicePage := ecs.NewListServicesPaginator(svc, &ecs.ListServicesInput{
    59  				Cluster: &clusterArn,
    60  			})
    61  			for servicePage.HasMorePages() {
    62  				serviceNextPage, err := servicePage.NextPage(context.TODO())
    63  				if err != nil {
    64  					fmt.Println(err.Error())
    65  					continue
    66  				}
    67  				for _, serviceArn := range serviceNextPage.ServiceArns {
    68  					arnParts := strings.Split(serviceArn, "/")
    69  					serviceName := arnParts[len(arnParts)-1]
    70  
    71  					serResp, err := svc.DescribeServices(context.TODO(), &ecs.DescribeServicesInput{
    72  						Services: []string{
    73  							serviceName,
    74  						},
    75  						Cluster: &clusterArn,
    76  					})
    77  					if err != nil {
    78  						fmt.Println(err.Error())
    79  						continue
    80  					}
    81  					serviceDetails := serResp.Services[0]
    82  
    83  					g.Resources = append(g.Resources, terraformutils.NewResource(
    84  						serviceArn,
    85  						clusterName+"_"+serviceName,
    86  						"aws_ecs_service",
    87  						"aws",
    88  						map[string]string{
    89  							"task_definition": StringValue(serviceDetails.TaskDefinition),
    90  							"cluster":         clusterName,
    91  							"name":            serviceName,
    92  							"id":              serviceArn,
    93  						},
    94  						ecsAllowEmptyValues,
    95  						map[string]interface{}{},
    96  					))
    97  				}
    98  			}
    99  		}
   100  	}
   101  
   102  	taskDefinitionsMap := map[string]terraformutils.Resource{}
   103  	taskDefinitionsPage := ecs.NewListTaskDefinitionsPaginator(svc, &ecs.ListTaskDefinitionsInput{})
   104  	for taskDefinitionsPage.HasMorePages() {
   105  		taskDefinitionsNextPage, e := taskDefinitionsPage.NextPage(context.TODO())
   106  		if e != nil {
   107  			fmt.Println(e.Error())
   108  			continue
   109  		}
   110  		for _, taskDefinitionArn := range taskDefinitionsNextPage.TaskDefinitionArns {
   111  			arnParts := strings.Split(taskDefinitionArn, ":")
   112  			definitionWithFamily := arnParts[len(arnParts)-2]
   113  			revision, _ := strconv.Atoi(arnParts[len(arnParts)-1])
   114  
   115  			// fetch only latest revision of task definitions
   116  			if val, ok := taskDefinitionsMap[definitionWithFamily]; !ok || val.AdditionalFields["revision"].(int) < revision {
   117  				taskDefinitionsMap[definitionWithFamily] = terraformutils.NewResource(
   118  					taskDefinitionArn,
   119  					definitionWithFamily,
   120  					"aws_ecs_task_definition",
   121  					"aws",
   122  					map[string]string{
   123  						"task_definition":       taskDefinitionArn,
   124  						"container_definitions": "{}",
   125  						"family":                "test-task",
   126  						"arn":                   taskDefinitionArn,
   127  					},
   128  					[]string{},
   129  					map[string]interface{}{
   130  						"revision": revision,
   131  					},
   132  				)
   133  			}
   134  		}
   135  	}
   136  	for _, v := range taskDefinitionsMap {
   137  		delete(v.AdditionalFields, "revision")
   138  		g.Resources = append(g.Resources, v)
   139  	}
   140  
   141  	return nil
   142  }
   143  
   144  func (g *EcsGenerator) PostConvertHook() error {
   145  	for _, r := range g.Resources {
   146  		if r.InstanceInfo.Type != "aws_ecs_service" {
   147  			continue
   148  		}
   149  		if r.InstanceState.Attributes["propagate_tags"] == "NONE" {
   150  			delete(r.Item, "propagate_tags")
   151  		}
   152  		delete(r.Item, "iam_role")
   153  	}
   154  
   155  	return nil
   156  }