0
# Tag Holds Management
1
2
Protection mechanism for tag values by creating holds that prevent deletion, ensuring critical tags remain available for policy enforcement and resource organization. TagHolds provide a way to protect important TagValues from accidental deletion when they are in use by critical systems or policies.
3
4
## Capabilities
5
6
### Tag Hold Creation
7
8
Create holds on TagValues to prevent their deletion. This is a long-running operation.
9
10
```python { .api }
11
def create_tag_hold(
12
self,
13
request: CreateTagHoldRequest = None,
14
*,
15
parent: str = None,
16
tag_hold: TagHold = None,
17
retry: OptionalRetry = gapic_v1.method.DEFAULT,
18
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
19
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
20
) -> operation.Operation:
21
"""
22
Creates a TagHold which prevents the TagValue from being deleted. This is a long-running operation.
23
24
Args:
25
parent (str): The resource name of the TagValue to hold.
26
Format: tagValues/{tag_value_id}
27
tag_hold (TagHold): The TagHold resource to create
28
retry: Retry configuration for the request
29
timeout: Request timeout in seconds
30
metadata: Additional metadata to send with the request
31
32
Returns:
33
Operation: Long-running operation that resolves to the created TagHold
34
"""
35
```
36
37
Usage example:
38
39
```python
40
from google.cloud.resourcemanager import TagHoldsClient
41
from google.cloud.resourcemanager_v3.types import TagHold
42
43
client = TagHoldsClient()
44
45
new_hold = TagHold(
46
holder="projects/my-project-123/services/my-service",
47
origin="Policy Engine v2.1",
48
help_link="https://example.com/docs/tag-holds"
49
)
50
51
operation = client.create_tag_hold(
52
parent="tagValues/281484271805522", # TagValue to protect
53
tag_hold=new_hold
54
)
55
result = operation.result() # Wait for completion
56
print(f"Created TagHold: {result.name}")
57
print(f"Holder: {result.holder}")
58
print(f"Origin: {result.origin}")
59
```
60
61
### Tag Hold Listing
62
63
List all TagHolds for a specified TagValue.
64
65
```python { .api }
66
def list_tag_holds(
67
self,
68
request: ListTagHoldsRequest = None,
69
*,
70
parent: str = None,
71
retry: OptionalRetry = gapic_v1.method.DEFAULT,
72
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
73
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
74
) -> pagers.ListTagHoldsPager:
75
"""
76
Lists TagHolds under a TagValue.
77
78
Args:
79
parent (str): The resource name of the TagValue whose holds are to be listed.
80
Format: tagValues/{tag_value_id}
81
retry: Retry configuration for the request
82
timeout: Request timeout in seconds
83
metadata: Additional metadata to send with the request
84
85
Returns:
86
ListTagHoldsPager: An iterator over TagHolds that automatically
87
handles pagination
88
"""
89
```
90
91
Usage example:
92
93
```python
94
client = TagHoldsClient()
95
96
# List all TagHolds for a TagValue
97
for hold in client.list_tag_holds(parent="tagValues/281484271805522"):
98
print(f"TagHold: {hold.name}")
99
print(f" Holder: {hold.holder}")
100
print(f" Origin: {hold.origin}")
101
print(f" Created: {hold.create_time}")
102
if hold.help_link:
103
print(f" Help: {hold.help_link}")
104
```
105
106
### Tag Hold Deletion
107
108
Remove TagHolds to allow TagValue deletion. This is a long-running operation.
109
110
```python { .api }
111
def delete_tag_hold(
112
self,
113
request: DeleteTagHoldRequest = None,
114
*,
115
name: str = None,
116
retry: OptionalRetry = gapic_v1.method.DEFAULT,
117
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
118
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
119
) -> operation.Operation:
120
"""
121
Deletes a TagHold. This is a long-running operation.
122
123
Args:
124
name (str): The resource name of the TagHold to delete.
125
Format: tagValues/{tag_value_id}/tagHolds/{tag_hold_id}
126
retry: Retry configuration for the request
127
timeout: Request timeout in seconds
128
metadata: Additional metadata to send with the request
129
130
Returns:
131
Operation: Long-running operation with no return value
132
"""
133
```
134
135
Usage example:
136
137
```python
138
client = TagHoldsClient()
139
140
# Delete a specific TagHold
141
operation = client.delete_tag_hold(
142
name="tagValues/281484271805522/tagHolds/some-hold-id"
143
)
144
operation.result() # Wait for completion
145
print("TagHold deleted successfully")
146
147
# Now the TagValue can be deleted if no other holds exist
148
```
149
150
## Types
151
152
```python { .api }
153
class TagHold:
154
name: str # Resource name: tagValues/{tag_value_id}/tagHolds/{tag_hold_id}
155
holder: str # Resource name of the holder (e.g., service, project)
156
origin: str # Human-readable origin information
157
help_link: str # Optional URL with more information about the hold
158
create_time: timestamp_pb2.Timestamp # Creation timestamp
159
160
# Request/Response types
161
class CreateTagHoldRequest:
162
parent: str # TagValue resource name: tagValues/{tag_value_id}
163
tag_hold: TagHold
164
validate_only: bool # If true, validate request without creating
165
166
class ListTagHoldsRequest:
167
parent: str # TagValue resource name: tagValues/{tag_value_id}
168
page_token: str
169
page_size: int
170
filter: str # Optional filter expression
171
172
class ListTagHoldsResponse:
173
tag_holds: MutableSequence[TagHold]
174
next_page_token: str
175
176
class DeleteTagHoldRequest:
177
name: str # TagHold resource name
178
validate_only: bool
179
180
# Metadata types for long-running operations
181
class CreateTagHoldMetadata:
182
# Empty metadata message
183
184
class DeleteTagHoldMetadata:
185
# Empty metadata message
186
```
187
188
## Usage Patterns
189
190
### Policy Engine Integration
191
192
```python
193
from google.cloud.resourcemanager import TagHoldsClient, TagValuesClient
194
from google.cloud.resourcemanager_v3.types import TagHold
195
196
# Service that manages policy-critical tags
197
class PolicyTagManager:
198
def __init__(self):
199
self.holds_client = TagHoldsClient()
200
self.values_client = TagValuesClient()
201
self.service_name = "projects/my-project/services/policy-engine"
202
203
def protect_critical_tag(self, tag_value_name: str, policy_name: str):
204
"""Create a hold on a TagValue used by a critical policy."""
205
hold = TagHold(
206
holder=self.service_name,
207
origin=f"Critical policy: {policy_name}",
208
help_link="https://company.com/docs/tag-policies"
209
)
210
211
operation = self.holds_client.create_tag_hold(
212
parent=tag_value_name,
213
tag_hold=hold
214
)
215
return operation.result()
216
217
def release_tag_protection(self, hold_name: str):
218
"""Remove protection from a TagValue."""
219
operation = self.holds_client.delete_tag_hold(name=hold_name)
220
operation.result()
221
222
def list_protected_tags(self, tag_value_name: str):
223
"""List all protections on a TagValue."""
224
return list(self.holds_client.list_tag_holds(parent=tag_value_name))
225
226
# Usage
227
manager = PolicyTagManager()
228
229
# Protect a critical environment tag
230
hold = manager.protect_critical_tag(
231
"tagValues/281484271805522", # production environment tag
232
"prod-firewall-policy"
233
)
234
print(f"Protected tag with hold: {hold.name}")
235
236
# Later, when policy is updated, remove protection
237
manager.release_tag_protection(hold.name)
238
```
239
240
### Bulk Protection Management
241
242
```python
243
def protect_multiple_tags(client: TagHoldsClient, tag_values: list, holder: str):
244
"""Create holds on multiple TagValues."""
245
operations = []
246
247
for tag_value in tag_values:
248
hold = TagHold(
249
holder=holder,
250
origin="Bulk protection operation"
251
)
252
253
operation = client.create_tag_hold(
254
parent=tag_value,
255
tag_hold=hold
256
)
257
operations.append(operation)
258
259
# Wait for all operations to complete
260
results = [op.result() for op in operations]
261
return results
262
263
# Usage
264
critical_tags = [
265
"tagValues/281484271805522", # production
266
"tagValues/281484271805523", # security-critical
267
"tagValues/281484271805524", # compliance-required
268
]
269
270
holds = protect_multiple_tags(
271
TagHoldsClient(),
272
critical_tags,
273
"projects/security-team/services/tag-guardian"
274
)
275
```
276
277
## Notes
278
279
- TagHolds prevent TagValue deletion by creating dependencies
280
- Multiple holds can exist on a single TagValue from different holders
281
- All holds must be removed before a TagValue can be deleted
282
- TagHolds are useful for:
283
- Policy enforcement systems
284
- Compliance requirements
285
- Critical resource protection
286
- Preventing accidental deletion during maintenance
287
288
- The `holder` field should identify the service or system creating the hold
289
- The `origin` field provides human-readable context about why the hold exists
290
- The `help_link` field can provide documentation about the hold and how to resolve it