AWS Setting Hostname by Tag
From Scalar Managed Services Wiki
Overview
This page outlines a way in which you can make sure that the hostname on a instance matches the "Name" tag that you tagged it with when you lit it up.
This does not update DNS internal or external.
This process uses an IAM instance profile to give an instance the permission to see it's own tags.
This process depends on the instance using cloud-init to do the work on first boot.
This process is persistent; If you reboot the machine, it keep the same hostname as the "Name" tag that it had when it first booted.
This process updated /etc/hosts and /etc/sysconfig/
If you later change the tag, simple run /root/sethostnmae.sh again to update everything.
This process required that the pythin aws cli is installed.
This process works on and was test with a centos 7 instance YMMV.
This was my starting place: https://www.mind-it.info/2014/03/09/setting-ec2-hostname-via-tags/
Parts
In user data ( cloud-init ):
runcmd: - [ /usr/bin/pip2.7, install, --upgrade, awscli ] - [ /root/sethostname.sh ] packages: - python27-pip - python-pip write_files: - content: | SERVER=$(/usr/bin/aws ec2 describe-tags --region ca-central-1 --filters "Name=resource-id,Values=$(wget -q -O - http://169.254.169.254/latest/meta-data/instance-id)" "Name=key,Values=Name" --query 'Tags[*].Value' --output text) PRIVATE_IP=$(curl http://169.254.169.254/latest/meta-data/local-ipv4) sed -i "s/^\(HOSTNAME\s*=\s*\).*$/\1$SERVER/" /etc/sysconfig/network echo "$PRIVATE_IP $SERVER" >> /etc/hosts hostname $SERVER path: /root/sethostname.sh permissions: '0755' owner: root:root
You must give the instance an "instance profile" with the "describe tags" permission. ( http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeTags.html )
Here's how that's done with terraform, in this case a "render" instance.
data "template_file" "render_instance_policy_file" { template = "${file("templates/render_instance_policy.json.tpl")}" vars = { customer = "${var.customer}" project = "${var.customer}" } } resource "aws_iam_instance_profile" "render_iam_profile" { name = "render_iam_profile" roles = ["${aws_iam_role.render_instance_role.name}"] } resource "aws_iam_role_policy" "render_instance_policy" { name = "render_instance_policy" role = "${aws_iam_role.render_instance_role.id}" policy = "${data.template_file.render_instance_policy_file.rendered}" } resource "aws_iam_role" "render_instance_role" { name = "render_instance_role" path = "/" assume_role_policy = "${file("templates/assume_role_policy.json.tpl")}" } resource "aws_instance" "node" { ... iam_instance_profile = "${aws_iam_instance_profile.render_iam_profile.id}" ... }
render_instance_policy.json.tpl is :
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": "ec2:DescribeTags", "Resource": "*" } ] }
The dependencies are organized like this:
aws_instance -> aws_iam_instance_profile -> aws_iam_role -> aws_iam_role_policy -> policy_file