[英]Set hostname on EC2 using cloud-init and instance tags?
Is there a way to use the values from instance tags to set the hostname on an EC2 instance, using cloud-init in user-data?有没有办法使用实例标签中的值在用户数据中使用 cloud-init 来设置 EC2 实例上的主机名?
Something like this?是这样的吗?
#cloud-config
preserve_hostname: false
hostname: my-custom-hostname
fqdn: my-custom-hostname.local
manage_etc_hosts: true
Except using an instance tag, such a "Name" or "hostname".除了使用实例标签,例如“名称”或“主机名”。 I've seen some examples using Jinja templates, which seems to be along the right lines.我看过一些使用 Jinja 模板的示例,它们似乎是正确的。 But I'm not sure if/how to reference the instance tags in the user-data/cloud-init.但我不确定是否/如何在用户数据/云初始化中引用实例标签。 If this makes more sense to bake into the AMI, I don't mind that - it doesn't have to be user-data.如果这对融入 AMI 更有意义,我不介意 - 它不一定是用户数据。 However, I currently am running a hostmod.sh
shell script at instance launch that reads the tags, and sets the hostname.但是,我目前正在实例启动时运行hostmod.sh
shell 脚本,该脚本读取标签并设置主机名。
## template: jinja
preserve_hostname: false
hostname: {% tags.hostname %}
fqdn: {% tags.hostname %}.local
manage_etc_hosts: true
One idea that worked for me was use shell parameter expansion (I think that's the right term).对我有用的一个想法是使用 shell 参数扩展(我认为这是正确的术语)。 I am still maintaining my own script, baked into my AMI, but I prefer the template-like approach versus my previous script that used sed to modify the /etc/hosts
file.我仍在维护自己的脚本,嵌入到我的 AMI 中,但我更喜欢类似模板的方法,而不是我之前使用 sed 修改/etc/hosts
文件的脚本。
#!/bin/bash
# Get Name tag from AWS instance metadata
ec2id=$(curl http://169.254.169.254/latest/meta-data/instance-id)
hostname=$(aws ec2 describe-tags --filters "Name=resource-id,Values=$ec2id" "Name=key,Values=Name" --region us-east-1 | awk '/"Value":/ {print $2}' | tr -d '",')
fqdn="${hostname}.local"
# Write a new hosts file using variable expansion
cat >/etc/hosts <<EOF
# The following lines are desirable for IPv4 capable hosts
127.0.0.1 ${fqdn} ${hostname}
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4
# The following lines are desirable for IPv6 capable hosts
::1 ${fqdn} ${hostname}
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
EOF
I run the script via cloud-init defined in user data:我通过用户数据中定义的 cloud-init 运行脚本:
#cloud-config
runcmd:
- bash /usr/local/bin/hostmod.sh
I also tried creating the entire script within user data via cloud-config.我还尝试通过 cloud-config 在用户数据中创建整个脚本。 This works as well, but I split the file out to make it easier to manage separately in Ansible.这也可以,但我将文件拆分出来以便在 Ansible 中单独管理。
#cloud-config
write_files:
- path: /usr/local/bin/hostmod.sh
permissions: 0744
owner: root
content: |
#!/bin/bash
ec2id=$(curl http://169.254.169.254/latest/meta-data/instance-id)
hostname=$(aws ec2 describe-tags --filters "Name=resource-id,Values=$ec2id" "Name=key,Values=Name" --region us-east-1 | awk '/"Value":/ {print $2}' | tr -d '",')
fqdn="${hostname}.local"
cat >/etc/hosts <<EOF
# The following lines are desirable for IPv4 capable hosts
127.0.0.1 ${fqdn} ${hostname}
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4
# The following lines are desirable for IPv6 capable hosts
::1 ${fqdn} ${hostname}
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
EOF
runcmd:
- bash /usr/local/bin/hostmod.sh
This obviously doesn't change the hostname, which is a bit more platform dependent.这显然不会改变主机名,这更依赖于平台。 That is why I preferred to use cloud-init from the start.这就是为什么我从一开始就喜欢使用 cloud-init。 I may later add a similar template for updating the hostname.我稍后可能会添加一个类似的模板来更新主机名。
This script will allow you to update the Amazon Linux (v1) hostname configured in /etc/sysconfig/network
- both parts are necessary to correctly configure the hostname.此脚本将允许您更新在/etc/sysconfig/network
中配置的 Amazon Linux (v1) 主机名 - 这两个部分都是正确配置主机名所必需的。
#! /bin/bash
#
export EC2_AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
export EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed 's/[a-z]$//'`"
export ec2id=$(curl http://169.254.169.254/latest/meta-data/instance-id )
export ec2name=$(aws ec2 describe-tags --filters "Name=resource-id,Values=$ec2id" "Name=key,Values=Name" --region $EC2_REGION | awk '/"Value":/ {print $2}' | tr -d '",')
#
hostname ${ec2name}
cat > /etc/sysconfig/network << EOF
NETWORKING=yes
HOSTNAME=${ec2name}
NOZEROCONF=yes
EOF
I know this is from a few years back and there's a reasonable solution listed, but tags are now available (since jan'22) in the metadata as well ( https://aws.amazon.com/about-aws/whats-new/2022/01/instance-tags-amazon-ec2-instance-metadata-service/ ) ie curl http://169.254.169.254/latest/meta-data/tags/instance/Name我知道这是几年前的事情,并且列出了一个合理的解决方案,但是元数据中现在也可以使用标签(自 1 月 22 日起)( https://aws.amazon.com/about-aws/whats-new /2022/01/instance-tags-amazon-ec2-instance-metadata-service/ ) 即 curl http://169.254.169.254/latest/meta-data/tags/instance
Cheers //A干杯//一个
To expand @mack answer, a simple working script to read a tag hostname
is:要扩展@mack 答案,读取标签hostname
的简单工作脚本是:
#!/bin/bash
export TAG_HOSTNAME=$(curl -s http://169.254.169.254/latest/meta-data/tags/instance/hostname)
hostnamectl set-hostname "$TAG_HOSTNAME"
Note that you have to turn on making the instance metadata tags available to the EC2 instance, either via console:请注意,您必须通过控制台打开使实例元数据标签对 EC2 实例可用:
Or with Terraform, like this:或者使用 Terraform,像这样:
resource "aws_instance" "somevm" {
...
metadata_options {
http_endpoint = "enabled"
instance_metadata_tags = "enabled"
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.