Skip to content

Commit

Permalink
Merge pull request #22165 from hashicorp/b-events-bus-policy-diffs
Browse files Browse the repository at this point in the history
events/bus_policy: Fix diffs with policy
  • Loading branch information
YakDriver authored Dec 13, 2021
2 parents 16d4ee9 + e151577 commit a5897a0
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 21 deletions.
3 changes: 3 additions & 0 deletions .changelog/22165.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_cloudwatch_event_bus_policy: Fix erroneous diffs in `policy` when no changes made or policies are equivalent
```
32 changes: 27 additions & 5 deletions internal/service/events/bus_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tfiam "github.com/hashicorp/terraform-provider-aws/internal/service/iam"
Expand Down Expand Up @@ -42,6 +43,10 @@ func ResourceBusPolicy() *schema.Resource {
Required: true,
ValidateFunc: validation.StringIsJSON,
DiffSuppressFunc: verify.SuppressEquivalentPolicyDiffs,
StateFunc: func(v interface{}) string {
json, _ := structure.NormalizeJsonString(v)
return json
},
},
},
}
Expand All @@ -51,15 +56,20 @@ func resourceBusPolicyCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).EventsConn

eventBusName := d.Get("event_bus_name").(string)
policy := d.Get("policy").(string)

policy, err := structure.NormalizeJsonString(d.Get("policy").(string))

if err != nil {
return fmt.Errorf("policy (%s) is invalid JSON: %w", policy, err)
}

input := eventbridge.PutPermissionInput{
EventBusName: aws.String(eventBusName),
Policy: aws.String(policy),
}

log.Printf("[DEBUG] Creating EventBridge policy: %s", input)
_, err := conn.PutPermission(&input)
_, err = conn.PutPermission(&input)
if err != nil {
return fmt.Errorf("Creating EventBridge policy failed: %w", err)
}
Expand Down Expand Up @@ -119,7 +129,13 @@ func resourceBusPolicyRead(d *schema.ResourceData, meta interface{}) error {
}
d.Set("event_bus_name", busName)

d.Set("policy", policy)
policyToSet, err := verify.PolicyToSet(d.Get("policy").(string), aws.StringValue(policy))

if err != nil {
return err
}

d.Set("policy", policyToSet)

return nil
}
Expand All @@ -140,13 +156,19 @@ func resourceBusPolicyUpdate(d *schema.ResourceData, meta interface{}) error {

eventBusName := d.Id()

policy, err := structure.NormalizeJsonString(d.Get("policy").(string))

if err != nil {
return fmt.Errorf("policy (%s) is invalid JSON: %w", policy, err)
}

input := eventbridge.PutPermissionInput{
EventBusName: aws.String(eventBusName),
Policy: aws.String(d.Get("policy").(string)),
Policy: aws.String(policy),
}

log.Printf("[DEBUG] Update EventBridge Bus policy: %s", input)
_, err := conn.PutPermission(&input)
_, err = conn.PutPermission(&input)
if tfawserr.ErrMessageContains(err, eventbridge.ErrCodeResourceNotFoundException, "") {
log.Printf("[WARN] EventBridge Bus %q not found, removing from state", d.Id())
d.SetId("")
Expand Down
112 changes: 96 additions & 16 deletions internal/service/events/bus_policy_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package events_test

import (
"encoding/json"
"fmt"
"reflect"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/eventbridge"
awspolicy "github.com/hashicorp/awspolicyequivalence"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
Expand Down Expand Up @@ -49,6 +48,31 @@ func TestAccEventsBusPolicy_basic(t *testing.T) {
})
}

func TestAccEventsBusPolicy_ignoreEquivalent(t *testing.T) {
resourceName := "aws_cloudwatch_event_bus_policy.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, eventbridge.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckBusDestroy,
Steps: []resource.TestStep{
{
Config: testAccBusPolicyOrderConfig(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckBusPolicyExists(resourceName),
testAccBusPolicyDocument(resourceName),
),
},
{
Config: testAccBusPolicyNewOrderConfig(rName),
PlanOnly: true,
},
},
})
}

func TestAccEventsBusPolicy_disappears(t *testing.T) {
resourceName := "aws_cloudwatch_event_bus_policy.test"
rstring := sdkacctest.RandString(5)
Expand Down Expand Up @@ -113,12 +137,6 @@ func testAccBusPolicyDocument(pr string) resource.TestCheckFunc {
return fmt.Errorf("No ID is set")
}

var eventBusPolicyResourcePolicyDocument map[string]interface{}
err := json.Unmarshal([]byte(eventBusPolicyResource.Primary.Attributes["policy"]), &eventBusPolicyResourcePolicyDocument)
if err != nil {
return fmt.Errorf("Parsing EventBridge bus policy for '%s' failed: %w", pr, err)
}

eventBusName := eventBusPolicyResource.Primary.ID

input := &eventbridge.DescribeEventBusInput{
Expand All @@ -131,18 +149,12 @@ func testAccBusPolicyDocument(pr string) resource.TestCheckFunc {
return fmt.Errorf("Reading EventBridge bus policy for '%s' failed: %w", pr, err)
}

var describedEventBusPolicy map[string]interface{}
err = json.Unmarshal([]byte(*describedEventBus.Policy), &describedEventBusPolicy)

if err != nil {
return fmt.Errorf("Reading EventBridge bus policy for '%s' failed: %w", pr, err)
}
if describedEventBus.Policy == nil || len(*describedEventBus.Policy) == 0 {
return fmt.Errorf("Not found: %s", pr)
}

if !reflect.DeepEqual(describedEventBusPolicy, eventBusPolicyResourcePolicyDocument) {
return fmt.Errorf("EventBridge bus policy mismatch for '%s'", pr)
if equivalent, err := awspolicy.PoliciesAreEquivalent(eventBusPolicyResource.Primary.Attributes["policy"], aws.StringValue(describedEventBus.Policy)); err != nil || !equivalent {
return fmt.Errorf("EventBridge bus policy not equivalent for '%s'", pr)
}

return nil
Expand Down Expand Up @@ -223,3 +235,71 @@ resource "aws_cloudwatch_event_bus_policy" "test" {
}
`, name)
}

func testAccBusPolicyOrderConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_cloudwatch_event_bus" "test" {
name = %[1]q
}
resource "aws_cloudwatch_event_bus_policy" "test" {
event_bus_name = aws_cloudwatch_event_bus.test.name
policy = jsonencode({
Statement = [{
Sid = %[1]q
Action = [
"events:PutEvents",
"events:PutRule",
"events:ListRules",
"events:DescribeRule",
]
Effect = "Allow"
Principal = {
Service = [
"ecs.amazonaws.com",
]
}
Resource = [
aws_cloudwatch_event_bus.test.arn,
]
}]
Version = "2012-10-17"
})
}
`, rName)
}

func testAccBusPolicyNewOrderConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_cloudwatch_event_bus" "test" {
name = %[1]q
}
resource "aws_cloudwatch_event_bus_policy" "test" {
event_bus_name = aws_cloudwatch_event_bus.test.name
policy = jsonencode({
Statement = [{
Sid = %[1]q
Action = [
"events:PutRule",
"events:DescribeRule",
"events:PutEvents",
"events:ListRules",
]
Effect = "Allow"
Principal = {
Service = [
"ecs.amazonaws.com",
]
}
Resource = [
aws_cloudwatch_event_bus.test.arn,
]
}]
Version = "2012-10-17"
})
}
`, rName)
}

0 comments on commit a5897a0

Please sign in to comment.