Deploying EC2 instances using AWSPowerShell, I find myself unable to apply tags on instance creation using the -TagSpecification
parameter in New-EC2Instance
. I am generating tags dynamically and the best I've been able to come up with so far still requires that I deploy the instance(s) without tags and then apply New-EC2Tag
to the captured InstanceID
s. My construction currently feels clunky and I can't shake the suspicion that waiting for the post-deploy tagging is just deferring poor object construction to a function with better error handling; even if that is the sample AWS guidance.
How do I clean up my implementation and allow on-deploy tagging?
Sample
Given Tag Spec construction like the following…
$tags = @'
{
"foo":"bar"
,"bing":"bong"
}
'@ | ConvertFrom-Json
$TagSpecification = @()
$tags.PSObject.Properties | ForEach-Object {
$tag = New-Object -TypeName Amazon.EC2.Model.Tag -ArgumentList @('Key', 'Value')
$tag.Key = $_.Name
$tag.Value = $_.Value
$TagSpecification += $tag
Remove-Variable tag
}
…attempting to apply tags on deploy in this way…
$newHost = New-EC2Instance ... -TagSpecification $TagSpecification ...
…results in the error:
New-EC2Instance : Cannot bind parameter 'TagSpecification'. Cannot convert the "Amazon.EC2.Model.Tag" value of type
"Amazon.EC2.Model.Tag" to type "Amazon.EC2.Model.TagSpecification".
However, if I omit the -TagSpecification
parameter at New-EC2Instance
invocation, I can use the $TagSpecification
object as constructed subsequently in the call:
New-EC2Tag -ResourceId $newHost.Instances.InstanceId -Tags $TagSpecification
So clearly, New-EC2Tag
has better handling for approximate object construction, but I have to assume there's a way to apply my tags in one call instead of two.
What am I doing wrong?
Best Answer
This seems to be the best way to go about it:
Basically you create the
TagSpecification
object, then you need to add theResourceType
you're targeting (see the below link to that type's doc page for a full list of valid ResourceType values).You can create the tags like this using the hashtable cast method, as it has a default (parameterless) constructor, and has publically settable properties. You could also create it first using a similar
::new()
method to the creation of the TagSpecification object and then manually fill in the Key and Value before adding it to the list of tags.This is also an option when it comes to tag creation:
Then, you add tags into the generic List referenced in the TagSpecification object's
.Tags
property.I pulled from the docs pages here in figuring this one out: https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TTag.html https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TTagSpecification.html