Skip to content

Commit b649d53

Browse files
Merge pull request #5844 from steve-thousand/sconrad/ACCT-10424_policy-state-drift
policy state drift
2 parents a362b28 + 5e7e2a8 commit b649d53

File tree

3 files changed

+111
-5
lines changed

3 files changed

+111
-5
lines changed

internal/services/api_token/resource_test.go

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,50 @@
11
package api_token_test
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
78
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
89
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
10+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
911
)
1012

1113
func TestAccAPIToken_Basic(t *testing.T) {
1214
rnd := utils.GenerateRandomResourceName()
1315
resourceID := "cloudflare_api_token." + rnd
1416
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
1517

18+
var policyId string
19+
1620
resource.Test(t, resource.TestCase{
17-
PreCheck: func() { acctest.TestAccPreCheck(t) },
21+
PreCheck: func() { acctest.TestAccPreCheck_APIToken(t) },
1822
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
1923
Steps: []resource.TestStep{
2024
{
2125
Config: testAccCloudflareAPITokenWithoutCondition(rnd, rnd, permissionID),
2226
Check: resource.ComposeTestCheckFunc(
2327
resource.TestCheckResourceAttr(resourceID, "name", rnd),
28+
resource.TestCheckResourceAttrSet(resourceID, "policies.0.id"),
29+
resource.TestCheckResourceAttrWith(resourceID, "policies.0.id", func(value string) error {
30+
policyId = value
31+
return nil
32+
}),
33+
resource.TestCheckResourceAttr(resourceID, "policies.0.permission_groups.0.id", permissionID),
2434
),
2535
},
2636
{
2737
Config: testAccCloudflareAPITokenWithoutCondition(rnd, rnd+"-updated", permissionID),
2838
Check: resource.ComposeTestCheckFunc(
2939
resource.TestCheckResourceAttr(resourceID, "name", rnd+"-updated"),
40+
resource.TestCheckResourceAttrSet(resourceID, "policies.0.id"),
41+
resource.TestCheckResourceAttrWith(resourceID, "policies.0.id", func(value string) error {
42+
if value != policyId {
43+
return fmt.Errorf("policy ID changed from %s to %s", policyId, value)
44+
}
45+
return nil
46+
}),
47+
resource.TestCheckResourceAttr(resourceID, "policies.0.permission_groups.0.id", permissionID),
3048
),
3149
},
3250
},
@@ -39,7 +57,7 @@ func TestAccAPIToken_DoesNotSetConditions(t *testing.T) {
3957
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
4058

4159
resource.Test(t, resource.TestCase{
42-
PreCheck: func() { acctest.TestAccPreCheck(t) },
60+
PreCheck: func() { acctest.TestAccPreCheck_APIToken(t) },
4361
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
4462
Steps: []resource.TestStep{
4563
{
@@ -64,7 +82,7 @@ func TestAccAPIToken_SetIndividualCondition(t *testing.T) {
6482
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
6583

6684
resource.Test(t, resource.TestCase{
67-
PreCheck: func() { acctest.TestAccPreCheck(t) },
85+
PreCheck: func() { acctest.TestAccPreCheck_APIToken(t) },
6886
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
6987
Steps: []resource.TestStep{
7088
{
@@ -89,7 +107,7 @@ func TestAccAPIToken_SetAllCondition(t *testing.T) {
89107
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
90108

91109
resource.Test(t, resource.TestCase{
92-
PreCheck: func() { acctest.TestAccPreCheck(t) },
110+
PreCheck: func() { acctest.TestAccPreCheck_APIToken(t) },
93111
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
94112
Steps: []resource.TestStep{
95113
{
@@ -114,7 +132,7 @@ func TestAccAPIToken_TokenTTL(t *testing.T) {
114132
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
115133

116134
resource.Test(t, resource.TestCase{
117-
PreCheck: func() { acctest.TestAccPreCheck(t) },
135+
PreCheck: func() { acctest.TestAccPreCheck_APIToken(t) },
118136
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
119137
Steps: []resource.TestStep{
120138
{
@@ -132,3 +150,67 @@ func TestAccAPIToken_TokenTTL(t *testing.T) {
132150
func testAccCloudflareAPITokenWithTTL(rnd string, permissionID string) string {
133151
return acctest.LoadTestCase("apitokenwithttl.tf", rnd, permissionID)
134152
}
153+
154+
func TestAccAPIToken_PermissionGroupOrder(t *testing.T) {
155+
rnd := utils.GenerateRandomResourceName()
156+
name := "cloudflare_api_token." + rnd
157+
permissionID1 := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
158+
permissionID2 := "e199d584e69344eba202452019deafe3" // Disable ESC read
159+
160+
resource.Test(t, resource.TestCase{
161+
PreCheck: func() { acctest.TestAccPreCheck_APIToken(t) },
162+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
163+
Steps: []resource.TestStep{
164+
{
165+
Config: acctest.LoadTestCase("api_token-permissiongroup-order.tf", rnd, permissionID1, permissionID2),
166+
Check: resource.ComposeTestCheckFunc(
167+
resource.TestCheckResourceAttr(name, "name", rnd),
168+
resource.TestCheckResourceAttr(name, "policies.0.permission_groups.0.id", permissionID1),
169+
resource.TestCheckResourceAttr(name, "policies.0.permission_groups.1.id", permissionID2),
170+
),
171+
},
172+
{
173+
Config: acctest.LoadTestCase("api_token-permissiongroup-order.tf", rnd, permissionID2, permissionID1),
174+
// changing the order of permission groups should not affect plan
175+
ConfigPlanChecks: resource.ConfigPlanChecks{
176+
PreApply: []plancheck.PlanCheck{
177+
plancheck.ExpectEmptyPlan(),
178+
},
179+
},
180+
},
181+
},
182+
})
183+
184+
resource.Test(t, resource.TestCase{
185+
PreCheck: func() { acctest.TestAccPreCheck_APIToken(t) },
186+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
187+
Steps: []resource.TestStep{
188+
{
189+
Config: acctest.LoadTestCase("api_token-permissiongroup-order.tf", rnd, permissionID2, permissionID1),
190+
Check: resource.ComposeTestCheckFunc(
191+
resource.TestCheckResourceAttr(name, "name", rnd),
192+
resource.TestCheckResourceAttr(name, "policies.0.permission_groups.0.id", permissionID1),
193+
resource.TestCheckResourceAttr(name, "policies.0.permission_groups.1.id", permissionID2),
194+
),
195+
},
196+
{
197+
Config: acctest.LoadTestCase("api_token-permissiongroup-order.tf", rnd, permissionID2, permissionID1),
198+
// re-applying same change does not produce drift
199+
ConfigPlanChecks: resource.ConfigPlanChecks{
200+
PreApply: []plancheck.PlanCheck{
201+
plancheck.ExpectEmptyPlan(),
202+
},
203+
},
204+
},
205+
{
206+
Config: acctest.LoadTestCase("api_token-permissiongroup-order.tf", rnd, permissionID1, permissionID2),
207+
// changing the order of permission groups should not affect plan
208+
ConfigPlanChecks: resource.ConfigPlanChecks{
209+
PreApply: []plancheck.PlanCheck{
210+
plancheck.ExpectEmptyPlan(),
211+
},
212+
},
213+
},
214+
},
215+
})
216+
}

internal/services/api_token/schema.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ func ResourceSchema(ctx context.Context) schema.Schema {
3737
"id": schema.StringAttribute{
3838
Description: "Policy identifier.",
3939
Computed: true,
40+
PlanModifiers: []planmodifier.String{
41+
stringplanmodifier.UseStateForUnknown(),
42+
},
4043
},
4144
"effect": schema.StringAttribute{
4245
Description: "Allow or deny operations against the resources.\nAvailable values: \"allow\", \"deny\".",
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
resource "cloudflare_api_token" "%[1]s" {
2+
name = "%[1]s"
3+
status = "active"
4+
5+
policies = [{
6+
effect = "allow"
7+
permission_groups = [{
8+
id = "%[2]s"
9+
},{
10+
id = "%[3]s"
11+
}]
12+
resources = {
13+
"com.cloudflare.api.account.zone.*" = "*"
14+
}
15+
}]
16+
}
17+
18+
data "cloudflare_api_token" "%[1]s" {
19+
token_id = cloudflare_api_token.%[1]s.id
20+
depends_on = [cloudflare_api_token.%[1]s]
21+
}

0 commit comments

Comments
 (0)