如何在CloudFormation集群中让Amazon EC2实例获取彼此私有IP?
Great question—this is a super common scenario when building private clusters in AWS, and embedding a static script in your AMI isn’t the most reliable or scalable approach (though it might work for one-off cases). Let’s walk through the best tailored solutions for your setup:
1. AWS CloudMap (Recommended for Long-Term/Scalable Clusters)
CloudMap is AWS’s native service discovery tool, perfect for dynamic clusters like your ASG-managed instances. Here’s how to set it up:
- In your CloudFormation template, create a private DNS namespace tied to your VPC.
- Add a user data script to your EC2 launch template/configuration that registers the instance’s private IP with CloudMap on startup. Example snippet:
#!/bin/bash INSTANCE_IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4) aws servicediscovery register-instance \ --service-id YOUR_CLOUDMAP_SERVICE_ID \ --instance-id $(curl -s http://169.254.169.254/latest/meta-data/instance-id) \ --attributes "AWS_INSTANCE_IPV4=$INSTANCE_IP" - When the 3rd instance starts, it can query CloudMap to get all registered instance IPs with a simple CLI call:
aws servicediscovery discover-instances --service-id YOUR_CLOUDMAP_SERVICE_ID --query 'Instances[*].Attributes.AWS_INSTANCE_IPV4' --output text
Why this works: CloudMap automatically handles instance registration/deregistration if your ASG scales up/down, and since it’s tied to your private VPC, no public IP is needed (just make sure your instances have an IAM role with servicediscovery:RegisterInstance and servicediscovery:DiscoverInstances permissions).
2. Query EC2 API via IAM Role (Simple, No Extra Services)
If you want a lightweight approach without adding another AWS service, use the EC2 API directly:
- Attach an IAM role to your ASG instances that allows the
ec2:DescribeInstancesaction. - Create a VPC endpoint for EC2 in your VPC (since your instances have no public IP, this lets them access the EC2 API privately).
- On the 3rd instance, run a script to filter instances by your ASG’s name tag:
#!/bin/bash ASG_NAME="Your-ASG-Name" aws ec2 describe-instances \ --filters "Name=tag:aws:autoscaling:groupName,Values=$ASG_NAME" \ --query 'Reservations[*].Instances[*].PrivateIpAddress' \ --output text
Why this works: It leverages AWS’s native tagging and API to dynamically fetch all instances in your ASG. No manual IP management required, and it’s easy to implement in your CloudFormation template.
3. CloudFormation Custom Resource + SSM Parameter Store (For Deployment-Time IP Collection)
If you need to collect all cluster IPs during the CloudFormation deployment (e.g., for initial cluster configuration), use a custom Lambda resource:
- Add a Lambda function to your CloudFormation template that:
- Fetches all instances in your ASG using
autoscaling:DescribeAutoScalingGroupsandec2:DescribeInstances. - Stores the list of private IPs in an SSM Parameter Store parameter.
- Fetches all instances in your ASG using
- Give your EC2 instances an IAM role with permission to read from that SSM parameter.
- On startup, the 3rd instance can pull the IP list with:
aws ssm get-parameter --name "/your/cluster/ips" --query 'Parameter.Value' --output text
Why this works: It centralizes the IP list during deployment, making it easy for all instances to access a single source of truth. Just ensure your VPC has an SSM endpoint for private access.
Why Embedding a Script in the AMI Isn’t Ideal
Embedding a script to "output" an IP only solves half the problem—your script can only get the local instance’s IP, not the others. Even if you tried to write the IP to a shared storage (like EFS), you’d still need a way for instances to discover that storage and sync data, which adds unnecessary complexity compared to the native AWS tools above.
内容的提问来源于stack exchange,提问作者Sandip Divekar

