CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-google-cloud-resource-manager

Google Cloud Resource Manager API client library for managing projects, folders, organizations, and tags in Google Cloud Platform

Pending
Overview
Eval results
Files

tag-holds.mddocs/

Tag Holds Management

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.

Capabilities

Tag Hold Creation

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}")

Tag Hold Listing

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}")

Tag Hold Deletion

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 exist

Types

class 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 message

Usage Patterns

Policy Engine Integration

from 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)

Bulk Protection Management

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"
)

Notes

  • 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:

    • Policy enforcement systems
    • Compliance requirements
    • Critical resource protection
    • Preventing accidental deletion during maintenance
  • 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

docs

folders.md

index.md

organizations.md

projects.md

tag-bindings.md

tag-holds.md

tag-keys.md

tag-values.md

tile.json