Google Cloud Resource Manager API client library for managing projects, folders, organizations, and tags in Google Cloud Platform
—
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.
Create holds on TagValues to prevent their deletion. This is a long-running operation.
def create_tag_hold(
self,
request: CreateTagHoldRequest = None,
*,
parent: str = None,
tag_hold: TagHold = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
) -> operation.Operation:
"""
Creates a TagHold which prevents the TagValue from being deleted. This is a long-running operation.
Args:
parent (str): The resource name of the TagValue to hold.
Format: tagValues/{tag_value_id}
tag_hold (TagHold): The TagHold resource to create
retry: Retry configuration for the request
timeout: Request timeout in seconds
metadata: Additional metadata to send with the request
Returns:
Operation: Long-running operation that resolves to the created TagHold
"""Usage example:
from google.cloud.resourcemanager import TagHoldsClient
from google.cloud.resourcemanager_v3.types import TagHold
client = TagHoldsClient()
new_hold = TagHold(
holder="projects/my-project-123/services/my-service",
origin="Policy Engine v2.1",
help_link="https://example.com/docs/tag-holds"
)
operation = client.create_tag_hold(
parent="tagValues/281484271805522", # TagValue to protect
tag_hold=new_hold
)
result = operation.result() # Wait for completion
print(f"Created TagHold: {result.name}")
print(f"Holder: {result.holder}")
print(f"Origin: {result.origin}")List all TagHolds for a specified TagValue.
def list_tag_holds(
self,
request: ListTagHoldsRequest = None,
*,
parent: str = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
) -> pagers.ListTagHoldsPager:
"""
Lists TagHolds under a TagValue.
Args:
parent (str): The resource name of the TagValue whose holds are to be listed.
Format: tagValues/{tag_value_id}
retry: Retry configuration for the request
timeout: Request timeout in seconds
metadata: Additional metadata to send with the request
Returns:
ListTagHoldsPager: An iterator over TagHolds that automatically
handles pagination
"""Usage example:
client = TagHoldsClient()
# List all TagHolds for a TagValue
for hold in client.list_tag_holds(parent="tagValues/281484271805522"):
print(f"TagHold: {hold.name}")
print(f" Holder: {hold.holder}")
print(f" Origin: {hold.origin}")
print(f" Created: {hold.create_time}")
if hold.help_link:
print(f" Help: {hold.help_link}")Remove TagHolds to allow TagValue deletion. This is a long-running operation.
def delete_tag_hold(
self,
request: DeleteTagHoldRequest = None,
*,
name: str = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
) -> operation.Operation:
"""
Deletes a TagHold. This is a long-running operation.
Args:
name (str): The resource name of the TagHold to delete.
Format: tagValues/{tag_value_id}/tagHolds/{tag_hold_id}
retry: Retry configuration for the request
timeout: Request timeout in seconds
metadata: Additional metadata to send with the request
Returns:
Operation: Long-running operation with no return value
"""Usage example:
client = TagHoldsClient()
# Delete a specific TagHold
operation = client.delete_tag_hold(
name="tagValues/281484271805522/tagHolds/some-hold-id"
)
operation.result() # Wait for completion
print("TagHold deleted successfully")
# Now the TagValue can be deleted if no other holds existclass TagHold:
name: str # Resource name: tagValues/{tag_value_id}/tagHolds/{tag_hold_id}
holder: str # Resource name of the holder (e.g., service, project)
origin: str # Human-readable origin information
help_link: str # Optional URL with more information about the hold
create_time: timestamp_pb2.Timestamp # Creation timestamp
# Request/Response types
class CreateTagHoldRequest:
parent: str # TagValue resource name: tagValues/{tag_value_id}
tag_hold: TagHold
validate_only: bool # If true, validate request without creating
class ListTagHoldsRequest:
parent: str # TagValue resource name: tagValues/{tag_value_id}
page_token: str
page_size: int
filter: str # Optional filter expression
class ListTagHoldsResponse:
tag_holds: MutableSequence[TagHold]
next_page_token: str
class DeleteTagHoldRequest:
name: str # TagHold resource name
validate_only: bool
# Metadata types for long-running operations
class CreateTagHoldMetadata:
# Empty metadata message
class DeleteTagHoldMetadata:
# Empty metadata messagefrom google.cloud.resourcemanager import TagHoldsClient, TagValuesClient
from google.cloud.resourcemanager_v3.types import TagHold
# Service that manages policy-critical tags
class PolicyTagManager:
def __init__(self):
self.holds_client = TagHoldsClient()
self.values_client = TagValuesClient()
self.service_name = "projects/my-project/services/policy-engine"
def protect_critical_tag(self, tag_value_name: str, policy_name: str):
"""Create a hold on a TagValue used by a critical policy."""
hold = TagHold(
holder=self.service_name,
origin=f"Critical policy: {policy_name}",
help_link="https://company.com/docs/tag-policies"
)
operation = self.holds_client.create_tag_hold(
parent=tag_value_name,
tag_hold=hold
)
return operation.result()
def release_tag_protection(self, hold_name: str):
"""Remove protection from a TagValue."""
operation = self.holds_client.delete_tag_hold(name=hold_name)
operation.result()
def list_protected_tags(self, tag_value_name: str):
"""List all protections on a TagValue."""
return list(self.holds_client.list_tag_holds(parent=tag_value_name))
# Usage
manager = PolicyTagManager()
# Protect a critical environment tag
hold = manager.protect_critical_tag(
"tagValues/281484271805522", # production environment tag
"prod-firewall-policy"
)
print(f"Protected tag with hold: {hold.name}")
# Later, when policy is updated, remove protection
manager.release_tag_protection(hold.name)def protect_multiple_tags(client: TagHoldsClient, tag_values: list, holder: str):
"""Create holds on multiple TagValues."""
operations = []
for tag_value in tag_values:
hold = TagHold(
holder=holder,
origin="Bulk protection operation"
)
operation = client.create_tag_hold(
parent=tag_value,
tag_hold=hold
)
operations.append(operation)
# Wait for all operations to complete
results = [op.result() for op in operations]
return results
# Usage
critical_tags = [
"tagValues/281484271805522", # production
"tagValues/281484271805523", # security-critical
"tagValues/281484271805524", # compliance-required
]
holds = protect_multiple_tags(
TagHoldsClient(),
critical_tags,
"projects/security-team/services/tag-guardian"
)TagHolds prevent TagValue deletion by creating dependencies
Multiple holds can exist on a single TagValue from different holders
All holds must be removed before a TagValue can be deleted
TagHolds are useful for:
The holder field should identify the service or system creating the hold
The origin field provides human-readable context about why the hold exists
The help_link field can provide documentation about the hold and how to resolve it
Install with Tessl CLI
npx tessl i tessl/pypi-google-cloud-resource-manager