Skip to content

Commit da6cbee

Browse files
derekchu-googleniharika-98
authored andcommitted
Add new resource iam_projects_policy_binding. addresses hashicorp/terraform-provider-google#20198 (GoogleCloudPlatform#12302)
1 parent 627cc9a commit da6cbee

File tree

6 files changed

+331
-0
lines changed

6 files changed

+331
-0
lines changed

mmv1/products/iam3/FoldersPolicyBinding.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ async:
4747
error:
4848
path: 'error'
4949
message: 'message'
50+
include_project: true
5051
examples:
5152
- name: 'iam_folders_policy_binding'
5253
min_version: 'beta'

mmv1/products/iam3/OrganizationsPolicyBinding.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ async:
4747
error:
4848
path: 'error'
4949
message: 'message'
50+
include_project: true
5051
examples:
5152
- name: 'iam_organizations_policy_binding'
5253
min_version: 'beta'

mmv1/products/iam3/PrincipalAccessBoundaryPolicy.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ async:
4545
error:
4646
path: 'error'
4747
message: 'message'
48+
include_project: true
4849
examples:
4950
- name: 'iam_principal_access_boundary_policy'
5051
min_version: 'beta'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Copyright 2024 Google Inc.
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
---
15+
name: 'ProjectsPolicyBinding'
16+
description: A policy binding to a Project
17+
references:
18+
guides:
19+
'Apply a policy binding': 'https://cloud.google.com/iam/docs/principal-access-boundary-policies-create#create_binding'
20+
api: 'https://cloud.google.com/iam/docs/reference/rest/v3beta/projects.locations.policyBindings'
21+
min_version: 'beta'
22+
id_format: 'projects/{{project}}/locations/{{location}}/policyBindings/{{policy_binding_id}}'
23+
base_url: 'projects/{{project}}/locations/{{location}}/policyBindings'
24+
self_link: 'projects/{{project}}/locations/{{location}}/policyBindings/{{policy_binding_id}}'
25+
create_url: 'projects/{{project}}/locations/{{location}}/policyBindings?policyBindingId={{policy_binding_id}}'
26+
update_verb: 'PATCH'
27+
update_mask: true
28+
import_format:
29+
- 'projects/{{project}}/locations/{{location}}/policyBindings/{{policy_binding_id}}'
30+
timeouts:
31+
insert_minutes: 20
32+
update_minutes: 20
33+
delete_minutes: 20
34+
custom_code:
35+
post_delete: 'templates/terraform/post_delete/sleep.go.tmpl'
36+
autogen_async: true
37+
async:
38+
actions: ['create', 'delete', 'update']
39+
type: 'OpAsync'
40+
operation:
41+
base_url: '{{op_id}}'
42+
path: 'name'
43+
wait_ms: 1000
44+
result:
45+
path: 'response'
46+
resource_inside_response: true
47+
error:
48+
path: 'error'
49+
message: 'message'
50+
examples:
51+
- name: 'iam_projects_policy_binding'
52+
min_version: 'beta'
53+
primary_resource_id: 'my-project-binding'
54+
test_env_vars:
55+
org_id: 'ORG_ID'
56+
vars:
57+
pab_policy_id: 'my-pab-policy'
58+
display_name: 'test project binding'
59+
project_binding_id: 'test-project-binding'
60+
parameters:
61+
- name: 'location'
62+
type: String
63+
description: |
64+
The location of the Policy Binding
65+
url_param_only: true
66+
required: true
67+
immutable: true
68+
- name: 'policyBindingId'
69+
type: String
70+
description: |
71+
The Policy Binding ID.
72+
url_param_only: true
73+
required: true
74+
immutable: true
75+
properties:
76+
- name: 'name'
77+
type: String
78+
description: |
79+
The name of the policy binding in the format `{binding_parent/locations/{location}/policyBindings/{policy_binding_id}`
80+
output: true
81+
- name: 'uid'
82+
type: String
83+
description: |
84+
Output only. The globally unique ID of the policy binding. Assigned when the policy binding is created.
85+
output: true
86+
- name: 'etag'
87+
type: Fingerprint
88+
description: |
89+
Optional. The etag for the policy binding. If this is provided on update, it must match the server's etag.
90+
output: true
91+
- name: 'displayName'
92+
type: String
93+
description: |
94+
Optional. The description of the policy binding. Must be less than or equal to 63 characters.
95+
- name: 'annotations'
96+
type: KeyValueAnnotations
97+
description: |
98+
Optional. User defined annotations. See https://google.aip.dev/148#annotations for more details such as format and size limitations
99+
- name: 'target'
100+
type: NestedObject
101+
description: |
102+
Target is the full resource name of the resource to which the policy will be bound. Immutable once set.
103+
required: true
104+
properties:
105+
- name: 'principalSet'
106+
type: String
107+
description: |
108+
Required. Immutable. The resource name of the policy to be bound.
109+
The binding parent and policy must belong to the same Organization (or Project).
110+
immutable: true
111+
- name: 'policyKind'
112+
type: String
113+
description: |
114+
Immutable. The kind of the policy to attach in this binding. This
115+
field must be one of the following: - Left empty (will be automatically set
116+
to the policy kind) - The input policy kind Possible values: POLICY_KIND_UNSPECIFIED PRINCIPAL_ACCESS_BOUNDARY ACCESS
117+
immutable: true
118+
- name: 'policy'
119+
type: String
120+
description: |
121+
Required. Immutable. The resource name of the policy to be bound. The binding parent and policy must belong to the same Organization (or Project).
122+
required: true
123+
immutable: true
124+
- name: 'policyUid'
125+
type: String
126+
description: |
127+
Output only. The globally unique ID of the policy to be bound.
128+
output: true
129+
- name: 'condition'
130+
type: NestedObject
131+
description: |
132+
Represents a textual expression in the Common Expression Language
133+
(CEL) syntax. CEL is a C-like expression language. The syntax and semantics of
134+
CEL are documented at https://github.com/google/cel-spec.
135+
Example (Comparison):
136+
title: \"Summary size limit\"
137+
description: \"Determines if a summary is less than 100 chars\"
138+
expression: \"document.summary.size() < 100\"
139+
Example
140+
(Equality):
141+
title: \"Requestor is owner\"
142+
description: \"Determines if requestor is the document owner\"
143+
expression: \"document.owner == request.auth.claims.email\" Example
144+
(Logic):
145+
title: \"Public documents\"
146+
description: \"Determine whether the document should be publicly visible\"
147+
expression: \"document.type != 'private' && document.type != 'internal'\"
148+
Example (Data Manipulation):
149+
title: \"Notification string\"
150+
description: \"Create a notification string with a timestamp.\"
151+
expression: \"'New message received at ' + string(document.create_time)\"
152+
The exact variables and functions that may be referenced within an expression are
153+
determined by the service that evaluates it. See the service documentation for
154+
additional information.
155+
properties:
156+
- name: 'expression'
157+
type: String
158+
description: |
159+
Textual representation of an expression in Common Expression Language syntax.
160+
- name: 'title'
161+
type: String
162+
description: |
163+
Optional. Title for the expression, i.e. a short string describing its purpose. This can be used e.g. in UIs which allow to enter the expression.
164+
- name: 'description'
165+
type: String
166+
description: |
167+
Optional. Description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI.
168+
- name: 'location'
169+
type: String
170+
description: |
171+
Optional. String indicating the location of the expression for error reporting, e.g. a file name and a position in the file.
172+
- name: 'createTime'
173+
type: String
174+
description: |
175+
Output only. The time when the policy binding was created.
176+
output: true
177+
- name: 'updateTime'
178+
type: String
179+
description: |
180+
Output only. The time when the policy binding was most recently updated.
181+
output: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
data "google_project" "project" {
2+
provider = google-beta
3+
}
4+
5+
resource "google_iam_principal_access_boundary_policy" "pab_policy" {
6+
provider = google-beta
7+
organization = "{{index $.TestEnvVars "org_id"}}"
8+
location = "global"
9+
display_name = "{{index $.Vars "display_name"}}"
10+
principal_access_boundary_policy_id = "{{index $.Vars "pab_policy_id"}}"
11+
}
12+
13+
resource "google_iam_projects_policy_binding" "{{$.PrimaryResourceId}}" {
14+
provider = google-beta
15+
project = data.google_project.project.project_id
16+
location = "global"
17+
display_name = "{{index $.Vars "display_name"}}"
18+
policy_kind = "PRINCIPAL_ACCESS_BOUNDARY"
19+
policy_binding_id = "{{index $.Vars "project_binding_id"}}"
20+
policy = "organizations/{{index $.TestEnvVars "org_id"}}/locations/global/principalAccessBoundaryPolicies/${google_iam_principal_access_boundary_policy.pab_policy.principal_access_boundary_policy_id}"
21+
target {
22+
principal_set = "//cloudresourcemanager.googleapis.com/projects/${data.google_project.project.project_id}"
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package iam3_test
2+
{{- if ne $.TargetVersionName "ga" }}
3+
4+
import (
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
8+
9+
"github.com/hashicorp/terraform-provider-google/google/acctest"
10+
"github.com/hashicorp/terraform-provider-google/google/envvar"
11+
)
12+
13+
func TestAccIAM3ProjectsPolicyBinding_iamProjectsPolicyBindingExample_update(t *testing.T) {
14+
t.Parallel()
15+
16+
context := map[string]interface{}{
17+
"org_id": envvar.GetTestOrgFromEnv(t),
18+
"random_suffix": acctest.RandString(t, 10),
19+
}
20+
21+
acctest.VcrTest(t, resource.TestCase{
22+
PreCheck: func() { acctest.AccTestPreCheck(t) },
23+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
24+
CheckDestroy: testAccCheckIAM3ProjectsPolicyBindingDestroyProducer(t),
25+
Steps: []resource.TestStep{
26+
{
27+
Config: testAccIAM3ProjectsPolicyBinding_iamProjectsPolicyBindingExample_full(context),
28+
},
29+
{
30+
ResourceName: "google_iam_projects_policy_binding.my-project-binding",
31+
ImportState: true,
32+
ImportStateVerify: true,
33+
ImportStateVerifyIgnore: []string{"annotations", "location", "policy_binding_id"},
34+
},
35+
{
36+
Config: testAccIAM3ProjectsPolicyBinding_iamProjectsPolicyBindingExample_update(context),
37+
},
38+
{
39+
ResourceName: "google_iam_projects_policy_binding.my-project-binding",
40+
ImportState: true,
41+
ImportStateVerify: true,
42+
ImportStateVerifyIgnore: []string{"annotations", "location", "policy_binding_id"},
43+
},
44+
{
45+
Config: testAccIAM3ProjectsPolicyBinding_iamProjectsPolicyBindingExample_full(context),
46+
},
47+
{
48+
ResourceName: "google_iam_projects_policy_binding.my-project-binding",
49+
ImportState: true,
50+
ImportStateVerify: true,
51+
ImportStateVerifyIgnore: []string{"annotations", "location", "policy_binding_id"},
52+
},
53+
54+
},
55+
})
56+
}
57+
58+
func testAccIAM3ProjectsPolicyBinding_iamProjectsPolicyBindingExample_full(context map[string]interface{}) string {
59+
return acctest.Nprintf(`
60+
resource "google_iam_principal_access_boundary_policy" "pab_policy" {
61+
provider = google-beta
62+
organization = "%{org_id}"
63+
location = "global"
64+
display_name = "test project binding%{random_suffix}"
65+
principal_access_boundary_policy_id = "tf-test-my-pab-policy%{random_suffix}"
66+
}
67+
68+
data "google_project" "project" {
69+
provider = google-beta
70+
}
71+
72+
resource "google_iam_projects_policy_binding" "my-project-binding" {
73+
provider = google-beta
74+
project = data.google_project.project.project_id
75+
location = "global"
76+
display_name = "test project binding%{random_suffix}"
77+
policy_kind = "PRINCIPAL_ACCESS_BOUNDARY"
78+
policy_binding_id = "tf-test-project-binding%{random_suffix}"
79+
policy = "organizations/%{org_id}/locations/global/principalAccessBoundaryPolicies/${google_iam_principal_access_boundary_policy.pab_policy.principal_access_boundary_policy_id}"
80+
target {
81+
principal_set = "//cloudresourcemanager.googleapis.com/projects/${data.google_project.project.project_id}"
82+
}
83+
}
84+
`, context)
85+
}
86+
87+
func testAccIAM3ProjectsPolicyBinding_iamProjectsPolicyBindingExample_update(context map[string]interface{}) string {
88+
return acctest.Nprintf(`
89+
resource "google_iam_principal_access_boundary_policy" "pab_policy" {
90+
provider = google-beta
91+
organization = "%{org_id}"
92+
location = "global"
93+
display_name = "test project binding%{random_suffix}"
94+
principal_access_boundary_policy_id = "tf-test-my-pab-policy%{random_suffix}"
95+
}
96+
97+
data "google_project" "project" {
98+
provider = google-beta
99+
}
100+
101+
resource "google_iam_projects_policy_binding" "my-project-binding" {
102+
provider = google-beta
103+
project = data.google_project.project.project_id
104+
location = "global"
105+
display_name = "test project binding%{random_suffix}"
106+
policy_kind = "PRINCIPAL_ACCESS_BOUNDARY"
107+
policy_binding_id = "tf-test-project-binding%{random_suffix}"
108+
policy = "organizations/%{org_id}/locations/global/principalAccessBoundaryPolicies/${google_iam_principal_access_boundary_policy.pab_policy.principal_access_boundary_policy_id}"
109+
annotations = {"foo": "bar"}
110+
target {
111+
principal_set = "//cloudresourcemanager.googleapis.com/projects/${data.google_project.project.project_id}"
112+
}
113+
condition {
114+
description = "test condition"
115+
expression = "principal.subject == '[email protected]'"
116+
location = "test location"
117+
title = "test title"
118+
}
119+
}
120+
`, context)
121+
}
122+
123+
{{- end }}

0 commit comments

Comments
 (0)