1

I have a CloudFormation stack that creates an EC2 instance and gives it a name tag.

I want to create a CloudWatch alarm, and reference the EC2 instance's name in the alarm's name - something like AlarmName: !Sub "Status Check Alarm - ${EC2InstanceName}".

!Ref will allow me to reference the CloudFormation script's parameters, but I don't want to parameterize the EC2 instance name - I don't want or need that to be customizable, and I don't want users to have the ability to choose a custom name for the server.

I tried outputting the EC2 instance name so I could !Ref that, but I got an Invalid template resource property 'Outputs' error, so I don't know if my approach even works:

EC2Instance:
  Properties: ...
  Type: AWS::EC2::Instance
  Outputs:
    EC2InstanceName:
      Description: The server's name.
      Value: !GetAtt EC2Instance.Tags.Name
      Export:
        Name: "EC2InstanceName"

How do I reference the EC2 instance's name without parameterizing the name at the top-level of the script?

EDIT:

I ended up using parameters anyway so I could !Ref them. I guess you could also set up an "allowed values" list containing only a single value that matches the default. It's lame but it works, I guess.

Parameters:
  EC2InstanceName:
    Type: String
    Default: "web-server-blah"
    Description: The name of the EC2 instance.
alex
  • 6,818
  • 9
  • 52
  • 103

2 Answers2

2

You can use !GetAtt only for attributes which are specifically named in the documentation https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html Tags are not among them.

But if you provide a different tag for your instance, then you can refer it without even exporting it (providing that it is a constant value).

I see what you are trying to do, but AWS does not support everything you would like to work out of the box. One way how I imagine it can be done - and you may not like it - is either via a macro or a custom resource (lambda function).

petrch
  • 1,807
  • 15
  • 19
  • Ouch. Yeah, I'm not going to try to hack this. I'm curious if there's a way to structure the CF templates to accommodate "name paramaterization", while at the same time still being friendly to AWS' visual infrastructure modeling tools. Any advice there is appreciated - thanks! – alex Feb 17 '22 at 16:03
  • 1
    Well, one reason why I like to work with AWS is that it is an "enterprise hacking platform". But I understand that that is not what you are looking for - at least not with this particular project. – petrch Feb 17 '22 at 19:57
-1

Can't use just use !Ref EC2Instance? I realize it won't be the friendly "Name" tag value, but it could be more useful, especially if you have duplicates of the same "Name". It would make your alarm be something like "Status Check Alarm - i-123456789".

Whereas if you use the name it might be something more like 10 alarms that read "Status Check Alarm - WWWServer", but now which WWWServer?

Tim Bassett
  • 1,325
  • 1
  • 12
  • 23
  • No, I definitely want the alarms to include the server's human-friendly names. I don't want the people monitoring those alarms to have to look up what a `i-1234567890abcdef` is all the time- that would be such a pain :( – alex Feb 17 '22 at 16:07