diff --git a/builtin/providers/aws/resource_aws_elasticsearch_domain.go b/builtin/providers/aws/resource_aws_elasticsearch_domain.go index 9b9adfaa8b..d680e435f9 100644 --- a/builtin/providers/aws/resource_aws_elasticsearch_domain.go +++ b/builtin/providers/aws/resource_aws_elasticsearch_domain.go @@ -22,9 +22,9 @@ func resourceAwsElasticSearchDomain() *schema.Resource { Schema: map[string]*schema.Schema{ "access_policies": &schema.Schema{ - Type: schema.TypeString, - StateFunc: normalizeJson, - Optional: true, + Type: schema.TypeString, + DiffSuppressFunc: suppressEquivalentAwsPolicyDiffs, + Optional: true, }, "advanced_options": &schema.Schema{ Type: schema.TypeMap, diff --git a/builtin/providers/aws/resource_aws_sns_topic.go b/builtin/providers/aws/resource_aws_sns_topic.go index 765874c2fb..c994b98add 100644 --- a/builtin/providers/aws/resource_aws_sns_topic.go +++ b/builtin/providers/aws/resource_aws_sns_topic.go @@ -46,9 +46,10 @@ func resourceAwsSnsTopic() *schema.Resource { ForceNew: false, }, "policy": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Computed: true, + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: suppressEquivalentAwsPolicyDiffs, StateFunc: func(v interface{}) string { s, ok := v.(string) if !ok || s == "" { diff --git a/builtin/providers/aws/resource_aws_sns_topic_test.go b/builtin/providers/aws/resource_aws_sns_topic_test.go index 2b74c7abb7..738614a258 100644 --- a/builtin/providers/aws/resource_aws_sns_topic_test.go +++ b/builtin/providers/aws/resource_aws_sns_topic_test.go @@ -7,8 +7,10 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/sns" + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/jen20/awspolicyequivalence" ) func TestAccAWSSNSTopic_basic(t *testing.T) { @@ -28,6 +30,26 @@ func TestAccAWSSNSTopic_basic(t *testing.T) { }) } +func TestAccAWSSNSTopic_policy(t *testing.T) { + rName := acctest.RandString(10) + expectedPolicy := `{"Statement":[{"Sid":"Stmt1445931846145","Effect":"Allow","Principal":{"AWS":"*"},"Action":"sns:Publish","Resource":"arn:aws:sns:us-west-2::example"}],"Version":"2012-10-17","Id":"Policy1445931846145"}` + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_sns_topic.test_topic", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSNSTopicDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSSNSTopicWithPolicy(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSNSTopicExists("aws_sns_topic.test_topic"), + testAccCheckAWSNSTopicHasPolicy("aws_sns_topic.test_topic", expectedPolicy), + ), + }, + }, + }) +} + func TestAccAWSSNSTopic_withIAMRole(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -45,6 +67,56 @@ func TestAccAWSSNSTopic_withIAMRole(t *testing.T) { }) } +func testAccCheckAWSNSTopicHasPolicy(n string, expectedPolicyText string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Queue URL specified!") + } + + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No SNS topic with that ARN exists") + } + + conn := testAccProvider.Meta().(*AWSClient).snsconn + + params := &sns.GetTopicAttributesInput{ + TopicArn: aws.String(rs.Primary.ID), + } + resp, err := conn.GetTopicAttributes(params) + if err != nil { + return err + } + + var actualPolicyText string + for k, v := range resp.Attributes { + if k == "Policy" { + actualPolicyText = *v + break + } + } + + equivalent, err := awspolicy.PoliciesAreEquivalent(actualPolicyText, expectedPolicyText) + if err != nil { + return fmt.Errorf("Error testing policy equivalence: %s", err) + } + if !equivalent { + return fmt.Errorf("Non-equivalent policy error:\n\nexpected: %s\n\n got: %s\n", + expectedPolicyText, actualPolicyText) + } + + return nil + } +} + func testAccCheckAWSSNSTopicDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).snsconn @@ -104,6 +176,31 @@ resource "aws_sns_topic" "test_topic" { } ` +func testAccAWSSNSTopicWithPolicy(r string) string { + return fmt.Sprintf(` +resource "aws_sns_topic" "test_topic" { + name = "example-%s" + policy = <