diff --git a/azurerm/internal/services/policy/resource_arm_policy_definition.go b/azurerm/internal/services/policy/resource_arm_policy_definition.go index 8714d12b4584..b1bef92cc577 100644 --- a/azurerm/internal/services/policy/resource_arm_policy_definition.go +++ b/azurerm/internal/services/policy/resource_arm_policy_definition.go @@ -2,8 +2,10 @@ package policy import ( "context" + "encoding/json" "fmt" "log" + "reflect" "strconv" "time" @@ -114,12 +116,35 @@ func resourceArmPolicyDefinition() *schema.Resource { Optional: true, Computed: true, ValidateFunc: validation.StringIsJSON, - DiffSuppressFunc: structure.SuppressJsonDiff, + DiffSuppressFunc: policyDefinitionsMetadataDiffSuppressFunc, }, }, } } +func policyDefinitionsMetadataDiffSuppressFunc(_, old, new string, _ *schema.ResourceData) bool { + var oldPolicyDefinitionsMetadata map[string]interface{} + errOld := json.Unmarshal([]byte(old), &oldPolicyDefinitionsMetadata) + if errOld != nil { + return false + } + + var newPolicyDefinitionsMetadata map[string]interface{} + errNew := json.Unmarshal([]byte(new), &newPolicyDefinitionsMetadata) + if errNew != nil { + return false + } + + // Ignore the following keys if they're found in the metadata JSON + ignoreKeys := [4]string{"createdBy", "createdOn", "updatedBy", "updatedOn"} + for _, key := range ignoreKeys { + delete(oldPolicyDefinitionsMetadata, key) + delete(newPolicyDefinitionsMetadata, key) + } + + return reflect.DeepEqual(oldPolicyDefinitionsMetadata, newPolicyDefinitionsMetadata) +} + func resourceArmPolicyDefinitionCreateUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*clients.Client).Policy.DefinitionsClient ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) diff --git a/azurerm/internal/services/policy/resource_arm_policy_set_definition.go b/azurerm/internal/services/policy/resource_arm_policy_set_definition.go index ac14ecc7f226..b7278f158f79 100644 --- a/azurerm/internal/services/policy/resource_arm_policy_set_definition.go +++ b/azurerm/internal/services/policy/resource_arm_policy_set_definition.go @@ -85,7 +85,7 @@ func resourceArmPolicySetDefinition() *schema.Resource { Optional: true, Computed: true, ValidateFunc: validation.StringIsJSON, - DiffSuppressFunc: structure.SuppressJsonDiff, + DiffSuppressFunc: policySetDefinitionsMetadataDiffSuppressFunc, }, "parameters": { @@ -105,6 +105,29 @@ func resourceArmPolicySetDefinition() *schema.Resource { } } +func policySetDefinitionsMetadataDiffSuppressFunc(_, old, new string, _ *schema.ResourceData) bool { + var oldPolicySetDefinitionsMetadata map[string]interface{} + errOld := json.Unmarshal([]byte(old), &oldPolicySetDefinitionsMetadata) + if errOld != nil { + return false + } + + var newPolicySetDefinitionsMetadata map[string]interface{} + errNew := json.Unmarshal([]byte(new), &newPolicySetDefinitionsMetadata) + if errNew != nil { + return false + } + + // Ignore the following keys if they're found in the metadata JSON + ignoreKeys := [4]string{"createdBy", "createdOn", "updatedBy", "updatedOn"} + for _, key := range ignoreKeys { + delete(oldPolicySetDefinitionsMetadata, key) + delete(newPolicySetDefinitionsMetadata, key) + } + + return reflect.DeepEqual(oldPolicySetDefinitionsMetadata, newPolicySetDefinitionsMetadata) +} + func policyDefinitionsDiffSuppressFunc(_, old, new string, _ *schema.ResourceData) bool { var oldPolicyDefinitions []policy.DefinitionReference errOld := json.Unmarshal([]byte(old), &oldPolicyDefinitions) diff --git a/azurerm/internal/services/policy/tests/resource_arm_policy_definition_test.go b/azurerm/internal/services/policy/tests/resource_arm_policy_definition_test.go index 4758625d44a1..9d4c476c7db2 100644 --- a/azurerm/internal/services/policy/tests/resource_arm_policy_definition_test.go +++ b/azurerm/internal/services/policy/tests/resource_arm_policy_definition_test.go @@ -84,6 +84,24 @@ func TestAccAzureRMPolicyDefinitionAtMgmtGroup_basic(t *testing.T) { }) } +func TestAccAzureRMPolicyDefinition_metadata(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_policy_definition", "test") + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMPolicyDefinitionDestroy, + Steps: []resource.TestStep{ + { + Config: testAzureRMPolicyDefinition_metadata(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPolicyDefinitionExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + func testCheckAzureRMPolicyDefinitionExistsInMgmtGroup(policyName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := acceptance.AzureProvider.Meta().(*clients.Client).Policy.DefinitionsClient @@ -336,3 +354,51 @@ PARAMETERS } `, data.RandomInteger, data.RandomInteger, data.RandomInteger) } + +func testAzureRMPolicyDefinition_metadata(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_policy_definition" "test" { + name = "acctestpol-%d" + policy_type = "Custom" + mode = "All" + display_name = "acctestpol-%d" + + policy_rule = <