Public/Set-CloudTag.ps1
|
function Set-CloudTag { <# .SYNOPSIS Sets tags or labels on a cloud resource across Azure, AWS, or GCP. .DESCRIPTION Set-CloudTag applies tags (Azure), tags (AWS), or labels (GCP) to cloud resources. For Azure, you can specify a VM by Name/ResourceGroup or any resource by ResourceId. For AWS, provide the ResourceId and Region. For GCP, provide the Project and Resource. You can also pipe CloudRecord objects from other PSCumulus commands. .EXAMPLE Set-CloudTag -Name 'vm01' -ResourceGroup 'rg-test' -Tags @{Environment='Dev'; Owner='TeamA'} Tags an Azure VM by name and resource group. .EXAMPLE Set-CloudTag -AzureResourceId '/subscriptions/123/resourceGroups/rg/providers/Microsoft.Compute/disks/disk01' -Tags @{Backup='Weekly'} Tags an Azure disk using its full resource ID (AzureById parameter set). .EXAMPLE Set-CloudTag -ResourceId 'i-1234567890abcdef0' -Region 'us-east-1' -Tags @{Environment='Prod'} Tags an AWS EC2 instance by its resource ID. .EXAMPLE Set-CloudTag -Project 'my-project' -Resource 'projects/my/zones/us-central1-a/instances/vm01' -Tags @{Owner='Ops'} Tags a GCP compute instance. .EXAMPLE Get-CloudDisk -Provider Azure | Set-CloudTag -Tags @{Encrypted='AES256'} Tags all Azure disks returned from Get-CloudDisk (piped input). #> [CmdletBinding( DefaultParameterSetName = 'Piped', SupportsShouldProcess = $true )] [OutputType([pscustomobject])] param( # The Azure VM name when tagging by name and resource group. [Parameter(Mandatory, ParameterSetName = 'AzureByName')] [string]$Name, # The Azure resource group containing the VM. [Parameter(Mandatory, ParameterSetName = 'AzureByName')] [string]$ResourceGroup, # The full Azure resource id to tag. [Parameter(Mandatory, ParameterSetName = 'AzureById')] [string]$AzureResourceId, # The AWS resource id to tag. [Parameter(Mandatory, ParameterSetName = 'AWS')] [string]$ResourceId, # The AWS region containing the resource. [Parameter(Mandatory, ParameterSetName = 'AWS')] [string]$Region, # The GCP project containing the resource. [Parameter(Mandatory, ParameterSetName = 'GCP')] [string]$Project, # The GCP resource path to label. [Parameter(Mandatory, ParameterSetName = 'GCP')] [string]$Resource, # A PSCumulus cloud record or object with Provider and Name properties. [Parameter(Mandatory, ValueFromPipeline = $true, ParameterSetName = 'Piped')] [psobject]$InputObject, # The tags or labels to apply. [Parameter(Mandatory)] [hashtable]$Tags, # Merge the supplied tags with existing tags instead of replacing them. [switch]$Merge ) begin { $results = [System.Collections.Generic.List[psobject]]::new() } process { $targetInfo = $null switch ($PSCmdlet.ParameterSetName) { 'AzureByName' { $subscriptionId = $script:PSCumulusContext.Providers['Azure'].SubscriptionId $targetInfo = @{ Provider = 'Azure' Name = $Name ResourceGroup = $ResourceGroup ResourceId = "/subscriptions/$subscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Compute/virtualMachines/$Name" } } 'AzureById' { $targetInfo = @{ Provider = 'Azure' ResourceId = $AzureResourceId Name = ($AzureResourceId -split '/')[-1] } } 'AWS' { $targetInfo = @{ Provider = 'AWS' ResourceId = $ResourceId Region = $Region } } 'GCP' { $targetInfo = @{ Provider = 'GCP' Project = $Project Resource = $Resource Name = $Resource -replace '.*/instances/' } } 'Piped' { if (-not $InputObject.Provider -or -not $InputObject.Name) { throw [System.ArgumentException]::new( "Set-CloudTag requires a PSCumulus CloudRecord, or any object with non-null Provider and Name properties." ) } $targetInfo = @{ Provider = $InputObject.Provider Name = $InputObject.Name InputObj = $InputObject } switch ($InputObject.Provider) { 'Azure' { $targetInfo.ResourceGroup = $InputObject.ResourceGroup $targetInfo.ResourceId = $InputObject.Id } 'AWS' { $targetInfo.ResourceId = $InputObject.InstanceId $targetInfo.Region = $InputObject.Region } 'GCP' { $targetInfo.Project = $InputObject.Project $targetInfo.Resource = $InputObject.Id } } } } if ($targetInfo) { $targetDisplay = switch ($targetInfo.Provider) { 'Azure' { if ($targetInfo.ResourceGroup) { "$($targetInfo.Name) (ResourceGroup: $($targetInfo.ResourceGroup))" } else { $targetInfo.ResourceId } } 'AWS' { "$($targetInfo.ResourceId) (Region: $($targetInfo.Region))" } 'GCP' { "$($targetInfo.Name) (Project: $($targetInfo.Project))" } } if ($PSCmdlet.ShouldProcess($targetDisplay, "Set tags $($Tags.Keys -join ', ')")) { $result = switch ($targetInfo.Provider) { 'Azure' { Set-AzureTag -ResourceId $targetInfo.ResourceId -Tags $Tags -Merge:$Merge } 'AWS' { Set-AWSTag -ResourceId $targetInfo.ResourceId -Tags $Tags -Merge:$Merge -Region $targetInfo.Region } 'GCP' { Set-GCPTag -Project $targetInfo.Project -Resource $targetInfo.Resource -Tags $Tags -Merge:$Merge } } if ($result) { $results.Add($result) } } } } end { $results | Write-Output } } |