Update AWS SNS topic tags with PowerShell

This short guide shows you how to add tags to SNS topics with PowerShell.

Requirements

Tested with:

To run the AWS Tools for PowerShell against an AWS account, you will need valid AWS credentials (i.e. Access Key ID and Secret Access Key).

Get-AWSPowerShellVersion

AWS Tools for PowerShell
Version 3.3.618.0
Copyright 2012-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Amazon Web Services SDK for .NET
Core Runtime Version 3.3.103.56
Copyright 2009-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Release notes: https://github.com/aws/aws-tools-for-powershell/blob/master/CHANGELOG.md

This software includes third party software subject to the following copyrights:
- Logging from log4net, Apache License
[http://logging.apache.org/log4net/license.html]

Solution

Get all available SNS topics:

$snstopics = Get-SNSTopic

Then if needed filter them, here I only want to get topics that contain the string coolproject_push_:

$snstopics | Where-Object topicarn -like "*coolproject_push_*" -Outvariable selectedTopics | Measure-Object

Count             : 71
Average           :
Sum               :
Maximum           :
Minimum           :
StandardDeviation :
Property          :

$selectedTopics | Select-Object -First 5

TopicArn
--------
arn:aws:sns:eu-west-1:012345678910:coolproject_push_02139RLpQaf_S0LzQdMZDgvJydfeyNINyzgNmW-qEb0
arn:aws:sns:eu-west-1:012345678910:coolproject_push_0a1rcYEoJW3u0GY5RiyTDRDxXakWXnYfG4I-3wZMhrQ
arn:aws:sns:eu-west-1:012345678910:coolproject_push_2FeuVnSTus_8cQajTxaknr7nj60y3H-OHEMDZNU8LQA
arn:aws:sns:eu-west-1:012345678910:coolproject_push_2SfPBTd0HA9kJEfpjRtsZCVMZBbRhORrDb-38xZX5r4
arn:aws:sns:eu-west-1:012345678910:coolproject_push_3001ZogFnNfzQPvKSHgfE2KJm80gbcOLoVmWzq8Pg8o

Next, define your tags:

$SNSTags  =  [Amazon.SimpleNotificationService.Model.Tag[]]@(
    @{Key="Project:productRef"; Value="cp"}
    @{Key="Project:market"; Value="global"}
    @{Key="Project:costCenter"; Value="CP1260-3"}
)

Finally, we’re going to apply them to our topics. Note that the Add-SNSResourceTag Cmdlet does not support pipeline input by property name so I have to loop over each topic.

Note:
I work with a read-only account by default to prevent accidental changes to our AWS infrastructure. But I forgot to explicitly specify an account that is allowed to change AWS resources, e.g. -ProfileName "seb":

Add-SNSResourceTag : User: arn:aws:iam::012345678910:user/usr-security-audit is not authorized to perform: SNS:TagResource on >resource: arn:aws:sns:eu-west-1:012345678910:coolproject_push_3001ZogFnNfzQPvKSHgfE2KJm80gbcOLoVmWzq8Pg8o
At line:1 char:69
+ ... t -f 5 | % {Add-SNSResourceTag -ResourceArn $_.TopicArn -Tag $SNSTags -P ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (Amazon.PowerShell.C\u2026NSResourceTagCmdlet:AddSNSResourceTagCmdlet) >[Add-SNSResourceTag], InvalidOperationException
+ FullyQualifiedErrorId : Amazon.SimpleNotificationService.Model.AuthorizationErrorException,>Amazon.PowerShell.Cmdlets.SNS.AddSNSResourceTagCmdlet

Just to be safe, I do a test run on a small subset of topics first and validate the results in the AWS SNS dashboard and on the command line:

$selectedTopics | Select-Object -First 5 | Foreach-Object {Add-SNSResourceTag -ResourceArn $_.TopicArn -Tag $SNSTags -PassThru  -ProfileName "seb" } -OutVariable FirstFiveTopics

$FirstFiveTopics[0] | Get-SNSResourceTag

Key                Value
---                -----
Project:productRef cp
Project:market     global
Project:costCenter CP1260-3

The tags were configured as expected so the rest of the topics could be updated:

$selectedTopics | Select-Object -Skip 5 | Foreach-Object {Add-SNSResourceTag -ResourceArn $_.TopicArn -Tag $SNSTags -PassThru  -ProfileName "seb" }