Skip to content

Commit

Permalink
Add a Terraform custom diff function to filter superfluous policy dif…
Browse files Browse the repository at this point in the history
…fs for Topic.sns

Signed-off-by: Alper Rifat Ulucinar <[email protected]>
  • Loading branch information
ulucinar committed Jun 6, 2024
1 parent 7b1b750 commit 747f4cb
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 5 deletions.
41 changes: 41 additions & 0 deletions config/sns/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ package sns

import (
"github.com/crossplane/upjet/pkg/config"
awspolicy "github.com/hashicorp/awspolicyequivalence"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"

"github.com/upbound/provider-aws/config/common"
)
Expand All @@ -26,5 +30,42 @@ func Configure(p *config.Provider) {
// If the topic policy is unset on the Topic resource, don't late initialize it, to avoid conflicts with the
// policy managed by a TopicPolicy resource.
r.LateInitializer.IgnoredFields = append(r.LateInitializer.IgnoredFields, "policy")
r.TerraformCustomDiff = func(diff *terraform.InstanceDiff, _ *terraform.InstanceState, _ *terraform.ResourceConfig) (*terraform.InstanceDiff, error) {
if diff == nil || diff.Attributes["policy"] == nil || diff.Attributes["policy"].Old == "" || diff.Attributes["policy"].New == "" {
return diff, nil
}

vOld, err := removePolicyVersion(diff.Attributes["policy"].Old)
if err != nil {
return nil, errors.Wrap(err, "failed to remove Version from the old AWS policy document")
}
vNew, err := removePolicyVersion(diff.Attributes["policy"].New)
if err != nil {
return nil, errors.Wrap(err, "failed to remove Version from the new AWS policy document")
}

ok, err := awspolicy.PoliciesAreEquivalent(vOld, vNew)
if err != nil {
return nil, errors.Wrap(err, "failed to compare the old and the new AWS policy documents")
}
if ok {
delete(diff.Attributes, "policy")
}
return diff, nil
}
})
}

func removePolicyVersion(p string) (string, error) {
var policy any
if err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(p), &policy); err != nil {
return "", errors.Wrap(err, "failed to unmarshal the policy from JSON")
}
m, ok := policy.(map[string]any)
if !ok {
return p, nil
}
delete(m, "Version")
r, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(m)
return string(r), errors.Wrap(err, "failed to marshal the policy map as JSON")
}
34 changes: 31 additions & 3 deletions examples/sns/v1beta1/topic-with-policy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
apiVersion: sns.aws.upbound.io/v1beta1
kind: Topic
metadata:
annotations:
meta.upbound.io/example-id: sns/v1beta1/topic
name: example-topic-${Rand.RFC1123Subdomain}
labels:
testing.upbound.io/example-name: sns
Expand All @@ -19,7 +21,7 @@ spec:
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456789110:role/test/project/test/principal1"
"arn:aws:iam::153891904029:role/sample-role"
]
},
"Action": "sns:Publish",
Expand All @@ -30,7 +32,7 @@ spec:
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456789110:role/test/project/test/principal1"
"arn:aws:iam::153891904029:role/sample-role"
]
},
"Action": "sns:GetTopicAttributes",
Expand All @@ -41,11 +43,37 @@ spec:
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456789110:role/test/project/test/principal1"
"arn:aws:iam::153891904029:role/sample-role"
]
},
"Action": "sns:ListSubscriptionsByTopic",
"Resource": "arn:aws:sns:us-west-1:123456789110:resource1"
}
]
}
---

apiVersion: iam.aws.upbound.io/v1beta1
kind: Role
metadata:
annotations:
meta.upbound.io/example-id: sns/v1beta1/topic
labels:
testing.upbound.io/example-name: role
name: sample-role
spec:
forProvider:
assumeRolePolicy: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ require (
github.com/crossplane/upjet v1.4.1
github.com/go-ini/ini v1.46.0
github.com/google/go-cmp v0.6.0
github.com/hashicorp/awspolicyequivalence v1.6.0
github.com/hashicorp/terraform-json v0.21.0
github.com/hashicorp/terraform-plugin-framework v1.8.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0
github.com/hashicorp/terraform-provider-aws v0.0.0-00010101000000-000000000000
github.com/json-iterator/go v1.1.12
github.com/pkg/errors v0.9.1
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/yaml.v3 v3.0.1
Expand Down Expand Up @@ -259,7 +261,6 @@ require (
github.com/hashicorp/aws-cloudformation-resource-schema-sdk-go v0.22.0 // indirect
github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.53 // indirect
github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2 v2.0.0-beta.54 // indirect
github.com/hashicorp/awspolicyequivalence v1.6.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
Expand Down Expand Up @@ -289,7 +290,6 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattbaird/jsonpatch v0.0.0-20230413205102-771768614e91 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
Expand Down

0 comments on commit 747f4cb

Please sign in to comment.