AWS - EC2用户数据脚本如何分配弹性IP?

6
我正在尝试为一个VPC创建自己的堡垒主机,并创建了一个最小/最大实例为1的自动扩展组。在我的启动配置中,我为ec2用户数据指定了以下内容:
#!

INSTANCE_ID=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id`

aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id eipalloc-my-eip-id --allow-reassociation

这个用户数据的目的是立即将弹性IP地址与我的新创建的EC2实例关联起来 - 我从其他StackOverflow帖子中了解到,在使用ASG时必须明确执行此操作。
然而,在ASG实例启动并完成初始化后,我仍然看不到任何实例的弹性IP地址输出到我的控制台:

enter image description here

我确认用户数据确实被实例使用: enter image description here 我尝试查看系统日志,以查看初始化期间是否有任何错误消息,但一开始我看不到任何暗示associate-address命令失败的内容(在/var/log/cloud-init-output内)。
编辑:尝试调试:
然而,我随后手动将弹性IP与我的实例关联,SSH并尝试运行上述用户数据命令。有趣的是,当我到达aws ec2 associate-address部分时,我遇到了
无法找到凭据。您可以通过运行“aws configure”来配置凭据。
这似乎是问题的根源-我的AWS配置文件未配置。但是,我一直认为,在实例完成初始化时,会为您设置默认的AWS实例配置文件,并具有访问AWS CLI的权限。
请问有人能指点我,为什么我的用户数据无法正确执行以关联弹性IP地址?

谢谢!

3个回答

7

你是否正在使用亚马逊提供的AMI运行你的EC2实例?

如果是这样,配置文件应该已经设置好了。但是我们注意到您的配置文件中默认区域没有设置。因此,在运行aws cli命令时,您需要使用--region <your region>来指定区域,或者设置AWS_DEFAULT_REGION环境变量。

我们使用以下脚本作为CloudFormation模板的一部分在启动时为我们的服务器配置EIP:

#!/bin/bash
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
MAXWAIT=3
ALLOC_ID=<your eip allocation id>
AWS_DEFAULT_REGION=<your region>

# Make sure the EIP is free
echo "Checking if EIP with ALLOC_ID[$ALLOC_ID] is free...."
ISFREE=$(aws ec2 describe-addresses --allocation-ids $ALLOC_ID --query Addresses[].InstanceId --output text)
STARTWAIT=$(date +%s)
while [ ! -z "$ISFREE" ]; do
    if [ "$(($(date +%s) - $STARTWAIT))" -gt $MAXWAIT ]; then
        echo "WARNING: We waited 30 seconds, we're forcing it now."
        ISFREE=""
    else
        echo "Waiting for EIP with ALLOC_ID[$ALLOC_ID] to become free...."
        sleep 3
        ISFREE=$(aws ec2 describe-addresses --allocation-ids $ALLOC_ID --query Addresses[].InstanceId --output text)
    fi
done

# Now we can associate the address
echo Running: aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOC_ID --allow-reassociation}
aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOC_ID --allow-reassociation}

我们已经添加了检查EIP是否空闲的部分,因为它被用于自动扩展组中,我们注意到有时即使旧实例已终止并且新实例正在运行用户数据脚本,EIP仍然在使用中。

不错的脚本!看一下被接受的答案-我忘记在ASG的启动配置中为我的实例分配IAM角色。但是检查可用的免费EIP地址是个好主意! - Yu Chen
啊,很高兴听到你已经通过实例角色解决了这个问题! - lotjuh

5

看起来这个EC2实例所附加的实例配置文件没有执行上述任务的权限。

参考https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-policies-ec2-console.html#ex-eip

请确保您的实例配置文件允许以下操作:

ec2:AllocateAddress: To allocate an Elastic IP address.

ec2:ReleaseAddress: To release an Elastic IP address.

ec2:AssociateAddress: To associate an Elastic IP address with an instance or a network interface.

ec2:DescribeNetworkInterfaces and ec2:DescribeInstances: To work with the Associate address screen. The screen displays the available instances or network interfaces to which you can associate an Elastic IP address.

ec2:DisassociateAddress: To disassociate an Elastic IP address from an instance or a network interface.

示例政策如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeAddresses",
                "ec2:AllocateAddress",
                "ec2:DescribeInstances",
                "ec2:AssociateAddress"
            ],
            "Resource": "*"
        }
    ]
}

希望这能帮到你。

就是这样了。它是使用 #!(来自其他答案)的组合,同时也允许我的 IAM 角色进行正确的地址关联操作。 - Yu Chen

3

用户数据脚本必须以#!开头才能被识别为脚本。例如:

#!
INSTANCE_ID=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id`

aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id eipalloc-xxx --allow-reassociation

您可以在/var/log/cloud-init-output.log中查看结果日志。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接