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

Yu *_*hen 6 amazon-ec2 amazon-web-services

我正在尝试为 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
Run Code Online (Sandbox Code Playgroud)

此用户数据的目标是立即将弹性 IP 地址与我新创建的 EC2 实例关联起来 -我从其他 StackOverflow 帖子中读到,在使用 ASG 时必须明确完成此操作。

但是,在 ASG 实例启动并完成初始化后,我在控制台输出中仍然看不到该实例的任何弹性 IP:

在此输入图像描述

我已经确认实例确实正在使用用户数据: 在此输入图像描述

我尝试查看系统日志内部,看看初始化期间是否有任何错误消息,但一开始我看不到任何表明命令associate-address失败的信息(内部/var/log/cloud-init-output)。

编辑:尝试调试:

但是,我随后手动将弹性 IP 与我的实例关联,通过 SSH 进行连接,并尝试运行上面的用户数据命令。有趣的是,当我到达该aws ec2 associate-address部分时,我遇到了

无法找到凭据。您可以通过运行“aws configure”来配置凭证。

这似乎是问题的根源 - 我的 AWS 配置文件未配置。但是,我一直认为默认的 AWS 实例配置文件已设置好,您可以在实例完成初始化后访问 AWS CLI。

谁能指出为什么我的用于关联弹性 IP 地址的用户数据可能无法正确执行?

谢谢你!

lot*_*juh 7

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

如果是这样,则确实应该设置配置文件。但是,我们注意到您的个人资料中未设置默认区域。因此,在运行aws cli命令时,您需要使用区域--region <your region>或设置AWS_DEFAULT_REGION环境变量。

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

#!/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}
Run Code Online (Sandbox Code Playgroud)

我们添加了检查 EIP 是否空闲的部分,因为这是在自动缩放组内使用的,并且我们注意到有时 EIP 仍在使用中,即使旧实例已经终止并且新实例处于此时运行 userdata 脚本。


pra*_*eep 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.
Run Code Online (Sandbox Code Playgroud)

示例策略如下所示:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeAddresses",
                "ec2:AllocateAddress",
                "ec2:DescribeInstances",
                "ec2:AssociateAddress"
            ],
            "Resource": "*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。