diff --git a/pkg/driftctl.go b/pkg/driftctl.go index 01f307b8..4c789fc2 100644 --- a/pkg/driftctl.go +++ b/pkg/driftctl.go @@ -53,6 +53,7 @@ func (d DriftCTL) Run() (*analyser.Analysis, error) { middlewares.NewAwsSqsQueuePolicyExpander(d.resourceFactory), middlewares.NewAwsDefaultSqsQueuePolicy(), middlewares.NewAwsSNSTopicPolicyExpander(d.resourceFactory), + middlewares.NewAwsDefaultIamRolePolicy(), ) logrus.Debug("Ready to run middlewares") diff --git a/pkg/middlewares/aws_iam_role_policy_defaults.go b/pkg/middlewares/aws_iam_role_policy_defaults.go new file mode 100644 index 00000000..f0f318a8 --- /dev/null +++ b/pkg/middlewares/aws_iam_role_policy_defaults.go @@ -0,0 +1,51 @@ +package middlewares + +import ( + "github.com/cloudskiff/driftctl/pkg/resource" + "github.com/cloudskiff/driftctl/pkg/resource/aws" + "github.com/sirupsen/logrus" +) + +// Default subnet should not be shown as unmanaged as they are present by default +// This middleware ignores default subnet from unmanaged resources if they are not managed by IaC +type AwsDefaultIamRolePolicy struct{} + +func NewAwsDefaultIamRolePolicy() AwsDefaultIamRolePolicy { + return AwsDefaultIamRolePolicy{} +} + +func (m AwsDefaultIamRolePolicy) Execute(remoteResources, resourcesFromState *[]resource.Resource) error { + + newRemoteResources := make([]resource.Resource, 0) + + for _, remoteResource := range *remoteResources { + existInState := false + + // Ignore all resources other than default Subnet + if remoteResource.TerraformType() != aws.AwsIamRolePolicyResourceType { + newRemoteResources = append(newRemoteResources, remoteResource) + continue + } + + for _, stateResource := range *resourcesFromState { + if resource.IsSameResource(remoteResource, stateResource) { + existInState = true + break + } + } + + if existInState { + newRemoteResources = append(newRemoteResources, remoteResource) + } else { + logrus.WithFields(logrus.Fields{ + "id": remoteResource.TerraformId(), + "type": remoteResource.TerraformType(), + }).Debug("Ignoring default IAM policies as it is not managed by IaC") + } + + } + + *remoteResources = newRemoteResources + + return nil +} diff --git a/pkg/middlewares/aws_iam_role_policy_defaults_test.go b/pkg/middlewares/aws_iam_role_policy_defaults_test.go new file mode 100644 index 00000000..3e98c8b6 --- /dev/null +++ b/pkg/middlewares/aws_iam_role_policy_defaults_test.go @@ -0,0 +1,100 @@ +package middlewares + +import ( + "strings" + "testing" + + awssdk "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/cloudskiff/driftctl/pkg/resource" + "github.com/cloudskiff/driftctl/pkg/resource/aws" + "github.com/r3labs/diff/v2" +) + +func TestAwsDefaultIamRolePolicy_Execute(t *testing.T) { + tests := []struct { + name string + remoteResources []resource.Resource + resourcesFromState []resource.Resource + expected []resource.Resource + }{ + { + "default iam role policies when they're not ignored when managed by IaC", + []resource.Resource{ + &aws.AwsIamRolePolicy{ + Id: "OrganizationAccountAccessRole:AdministratorAccess", + }, + &aws.AwsRoute{ + Id: "dummy-route", + RouteTableId: awssdk.String("default-route-table"), + GatewayId: awssdk.String("local"), + }, + }, + []resource.Resource{ + &aws.AwsRoute{ + Id: "dummy-route", + RouteTableId: awssdk.String("default-route-table"), + GatewayId: awssdk.String("local"), + }, + }, + []resource.Resource{ + &aws.AwsRoute{ + Id: "dummy-route", + RouteTableId: awssdk.String("default-route-table"), + GatewayId: awssdk.String("local"), + }, + }, + }, + { + "default iam role policies when they're not ignored when managed by IaC", + []resource.Resource{ + &aws.AwsIamRolePolicy{ + Id: "OrganizationAccountAccessRole:AdministratorAccess", + }, + &aws.AwsRoute{ + Id: "dummy-route", + RouteTableId: awssdk.String("default-route-table"), + GatewayId: awssdk.String("local"), + }, + }, + []resource.Resource{ + &aws.AwsIamRolePolicy{ + Id: "OrganizationAccountAccessRole:AdministratorAccess", + }, + &aws.AwsRoute{ + Id: "dummy-route", + RouteTableId: awssdk.String("default-route-table"), + GatewayId: awssdk.String("local"), + }, + }, + []resource.Resource{ + &aws.AwsIamRolePolicy{ + Id: "OrganizationAccountAccessRole:AdministratorAccess", + }, + &aws.AwsRoute{ + Id: "dummy-route", + RouteTableId: awssdk.String("default-route-table"), + GatewayId: awssdk.String("local"), + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := NewAwsDefaultIamRolePolicy() + err := m.Execute(&tt.remoteResources, &tt.resourcesFromState) + if err != nil { + t.Fatal(err) + } + changelog, err := diff.Diff(tt.expected, tt.remoteResources) + if err != nil { + t.Fatal(err) + } + if len(changelog) > 0 { + for _, change := range changelog { + t.Errorf("%s got = %v, want %v", strings.Join(change.Path, "."), awsutil.Prettify(change.From), awsutil.Prettify(change.To)) + } + } + }) + } +}