github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/aws/organization.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  
    21  	"github.com/GoogleCloudPlatform/terraformer/terraformutils"
    22  	"github.com/aws/aws-sdk-go-v2/aws"
    23  
    24  	"github.com/aws/aws-sdk-go-v2/service/organizations"
    25  	"github.com/aws/aws-sdk-go-v2/service/organizations/types"
    26  )
    27  
    28  var organizationAllowEmptyValues = []string{"tags."}
    29  
    30  type OrganizationGenerator struct {
    31  	AWSService
    32  }
    33  
    34  func (g *OrganizationGenerator) traverseNode(svc *organizations.Client, parentID string) {
    35  	accountsForParent, err := svc.ListAccountsForParent(context.TODO(),
    36  		&organizations.ListAccountsForParentInput{ParentId: aws.String(parentID)})
    37  	if err != nil {
    38  		return
    39  	}
    40  	for _, account := range accountsForParent.Accounts {
    41  		g.Resources = append(g.Resources, terraformutils.NewResource(
    42  			StringValue(account.Id),
    43  			StringValue(account.Name),
    44  			"aws_organizations_organization",
    45  			"aws",
    46  			map[string]string{
    47  				"id":  StringValue(account.Id),
    48  				"arn": StringValue(account.Arn),
    49  			},
    50  			organizationAllowEmptyValues,
    51  			map[string]interface{}{},
    52  		))
    53  		g.Resources = append(g.Resources, terraformutils.NewResource(
    54  			StringValue(account.Id),
    55  			StringValue(account.Name),
    56  			"aws_organizations_account",
    57  			"aws",
    58  			map[string]string{
    59  				"id":  StringValue(account.Id),
    60  				"arn": StringValue(account.Arn),
    61  			},
    62  			organizationAllowEmptyValues,
    63  			map[string]interface{}{},
    64  		))
    65  	}
    66  
    67  	unitsForParent, err := svc.ListOrganizationalUnitsForParent(context.TODO(),
    68  		&organizations.ListOrganizationalUnitsForParentInput{ParentId: aws.String(parentID)})
    69  	if err != nil {
    70  		return
    71  	}
    72  	for _, unit := range unitsForParent.OrganizationalUnits {
    73  		g.Resources = append(g.Resources, terraformutils.NewResource(
    74  			StringValue(unit.Id),
    75  			StringValue(unit.Name),
    76  			"aws_organizations_organizational_unit",
    77  			"aws",
    78  			map[string]string{
    79  				"id":  StringValue(unit.Id),
    80  				"arn": StringValue(unit.Arn),
    81  			},
    82  			organizationAllowEmptyValues,
    83  			map[string]interface{}{},
    84  		))
    85  		g.traverseNode(svc, StringValue(unit.Id))
    86  	}
    87  }
    88  
    89  func (g *OrganizationGenerator) InitResources() error {
    90  	config, e := g.generateConfig()
    91  	if e != nil {
    92  		return e
    93  	}
    94  	svc := organizations.NewFromConfig(config)
    95  
    96  	roots, err := svc.ListRoots(context.TODO(), &organizations.ListRootsInput{})
    97  	if err != nil {
    98  		return err
    99  	}
   100  
   101  	for _, root := range roots.Roots {
   102  		nodeID := StringValue(root.Id)
   103  		g.traverseNode(svc, nodeID)
   104  	}
   105  
   106  	p := organizations.NewListPoliciesPaginator(svc, &organizations.ListPoliciesInput{
   107  		Filter: types.PolicyTypeServiceControlPolicy,
   108  	})
   109  	for p.HasMorePages() {
   110  		page, err := p.NextPage(context.TODO())
   111  		if err != nil {
   112  			return err
   113  		}
   114  		for _, policy := range page.Policies {
   115  			policyID := StringValue(policy.Id)
   116  			policyName := StringValue(policy.Name)
   117  			g.Resources = append(g.Resources, terraformutils.NewResource(
   118  				policyID,
   119  				policyName,
   120  				"aws_organizations_policy",
   121  				"aws",
   122  				map[string]string{
   123  					"id":  policyID,
   124  					"arn": StringValue(policy.Arn),
   125  				},
   126  				organizationAllowEmptyValues,
   127  				map[string]interface{}{},
   128  			))
   129  
   130  			targetsForPolicy, err := svc.ListTargetsForPolicy(context.TODO(),
   131  				&organizations.ListTargetsForPolicyInput{PolicyId: policy.Id})
   132  			if err != nil {
   133  				fmt.Println(err.Error())
   134  				continue
   135  			}
   136  			for _, target := range targetsForPolicy.Targets {
   137  				g.Resources = append(g.Resources, terraformutils.NewResource(
   138  					StringValue(target.TargetId)+":"+policyID,
   139  					"pa-"+StringValue(target.TargetId)+":"+policyName,
   140  					"aws_organizations_policy_attachment",
   141  					"aws",
   142  					map[string]string{
   143  						"policy_id": policyID,
   144  						"target_id": StringValue(target.TargetId),
   145  					},
   146  					organizationAllowEmptyValues,
   147  					map[string]interface{}{},
   148  				))
   149  			}
   150  		}
   151  	}
   152  
   153  	return nil
   154  }