Author : MD TAREQ HASSAN | Updated : 2021/10/28

Adding Tag While Creating Resource

Create an Azure Resource Group with tags

var rgName = "DemoRg"

var resourceGroup = new ResourceGroup(rgName, new ResourceGroupArgs {

    ResourceGroupName = rgName,
    Location = "japaneast",
    Tags = { 
        ["tagKey1"] = "value1",
        ["tagKey2"] = "value2"
    }
});

// ... ... ...

TagAtScope Class

TagAtScope

[AzureNativeResourceTypeAttribute("azure-native:resources:TagAtScope")]
public class TagAtScope : CustomResource
{

    public TagAtScope(string name, TagAtScopeArgs args, CustomResourceOptions? options = null);

    // ... ... ...
}

TagAtScopeArgs

public sealed class TagAtScopeArgs : Pulumi.ResourceArgs
{
    public TagAtScopeArgs();

    public Input<TagsArgs> Properties { get; set; }

    public Input<string> Scope { get; set; }
}

API Doc: https://www.pulumi.com/registry/packages/azure-native/api-docs/resources/tagatscope/

Adding Tag To Exingting Resource

// Create Resource Group
var resourceGroup = new ResourceGroup("resourceGroup", new ResourceGroupArgs
{
    ResourceGroupName = "demo-rg",
    Location = "japaneast"
    //Tags = 
});

// Apply tags
var appliedTags = resourceGroup.Id.Apply(rgResourceId =>
{
    
    return new TagAtScope("demoTagAtScope", new TagAtScopeArgs
    {
        Scope = rgResourceId, // (scope) ResourceId -> xxx/yyy/zzz/...
        Properties = new TagsArgs()
        {
            Tags = {
                ["tagKey1"] = "value1",
                ["tagKey2"] = "value2"
            }
        }
    });
});

// ... ... ...

An existing resource can be imported using its type token, name, and identifier

pulumi import azure-native:resources:TagAtScope myresource1 /{scope}/providers/Microsoft.Resources/tags/default

Getting Tags from Stack Configuration

Pulumi.XxxDev.yaml

config:
  azure-native:location: japaneast # default location
  
  xxx:ResourceGroupArgs:
    ResourceGroupName: DemoRG
    Tags:
      CreatedBy: Pulumi
      Scope: Demo
namespace PulumiDemo
{
    class MyStack : Stack
    {
        public MyStack()
        {
            var config = new Config("xxx");
            
            //
            // Use Pulumi config to get ResourceGroupArgs from yaml (as json element)
            // Then exract configuration values from json element
            //
            var mainRgArgs = config.RequireObject<JsonElement>("ResourceGroupArgs");
            var mainRgName = mainRgArgs.GetProperty("ResourceGroupName").GetString()!;
            var mainRgTags = mainRgArgs.GetProperty("Tags").Deserialize<Dictionary<string, string>>()!; // .Deserialize -> available only in .Net 6.0+

            var mainRg = new ResourceGroup("ResourceGroupMain", new ResourceGroupArgs
            {
                ResourceGroupName = mainRgName,
                Tags = mainRgTags
            });
            
            // ... ... ...
        }
    }
}

Applying Common Tags using Transformations

namespace PulumiDemo
{
    class MyStack : Stack
    {
    
        internal static readonly ReadOnlyDictionary<string, string> CommonTags = new(new Dictionary<string, string>()
        {
            ["CreatedBy"] = "Pulumi",
            ["Scope"] = "Demo"
        });

        //
        // Apply common tags with ResourceTransformation
        // 
        static ResourceTransformation RegisterAutoTags(Dictionary<string, string> autoTags)
        {
            return (args) =>
            {
                ResourceTransformationResult? rtr = null;

                var tagp = args.Args.GetType().GetProperty("Tags");
                if (tagp != null)
                {
                    var tags = (InputMap<string>)tagp.GetValue(args.Args, null) ?? new InputMap<string>();
                    foreach (var tag in autoTags)
                    {
                        tags[tag.Key] = tag.Value;
                    }
                    tagp.SetValue(args.Args, tags, null);

                    rtr = new ResourceTransformationResult(args.Args, args.Options);
                }

                return rtr;
            };
        }
        
        public MyStack() : base(new StackOptions { ResourceTransformations = { RegisterAutoTags(CommonTags) }})
        {
          // ... ... ...
        }
    }
}