Cloud-init tips and tricks for EC2 instances
Working extensively with RunsOn, I’ve spent considerable time with cloud-init, the industry-standard tool that automatically configures cloud instances on startup. Present on Ubuntu distributions on AWS, cloud-init fetches metadata from the underlying cloud provider and applies initial configurations. Here are some useful commands and techniques I’ve discovered for troubleshooting and inspecting EC2 instances.
Querying user-data content
Section titled “Querying user-data content”When debugging instance startup issues, you often need to check what user-data was passed to your instance. Here are three ways to retrieve it:
1. Using cloud-init query (recommended)
Section titled “1. Using cloud-init query (recommended)”The most reliable method is using the built-in cloud-init query
command:
# View user datasudo cloud-init query userdata
# View all instance data including user datasudo cloud-init query --all
2. Reading from the filesystem
Section titled “2. Reading from the filesystem”Cloud-init stores user-data locally after fetching it:
# User data is stored insudo cat /var/lib/cloud/instance/user-data.txt
3. Using the instance metadata service (IMDS)
Section titled “3. Using the instance metadata service (IMDS)”You can also query the EC2 metadata service directly:
# IMDSv2 (recommended)TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/user-data
# IMDSv1 (legacy)curl http://169.254.169.254/latest/user-data
Accessing all EC2 metadata without additional API calls
Section titled “Accessing all EC2 metadata without additional API calls”Here’s a powerful tip: cloud-init automatically fetches all relevant data from the EC2 metadata API at startup and caches it locally. Instead of making multiple API calls, you can read everything from a single JSON file:
sudo cat /run/cloud-init/instance-data.json
This file contains a wealth of information about your instance. Let’s explore some useful queries:
Instance identity document
Section titled “Instance identity document”Get comprehensive instance details:
sudo cat /run/cloud-init/instance-data.json | jq '.ds.dynamic["instance-identity"].document'
Output:
{ "accountId": "135269210855", "architecture": "x86_64", "availabilityZone": "us-east-1b", "billingProducts": null, "devpayProductCodes": null, "imageId": "ami-0db4eca8382e7fc27", "instanceId": "i-00a3d21a80694c44b", "instanceType": "m7a.large", "kernelId": null, "marketplaceProductCodes": null, "pendingTime": "2025-04-25T12:00:18Z", "privateIp": "10.0.1.93", "ramdiskId": null, "region": "us-east-1", "version": "2017-09-30"}
Complete metadata
Section titled “Complete metadata”Access all EC2 metadata fields:
sudo cat /run/cloud-init/instance-data.json | jq '.ds["meta-data"]'
This reveals extensive information including:
- Network configuration (VPC, subnet, security groups)
- IAM instance profile details
- Block device mappings
- Hostname and IP addresses
- Maintenance events
Extracting specific values
Section titled “Extracting specific values”Need just the public IP? Or the instance type? Use jq to extract specific fields:
# Get public IPv4 addresssudo jq -r '.ds["meta-data"]["public-ipv4"]' /run/cloud-init/instance-data.json# Output: 3.93.38.69
# Get instance typesudo jq -r '.ds["meta-data"]["instance-type"]' /run/cloud-init/instance-data.json# Output: m7a.large
# Get availability zonesudo jq -r '.ds["meta-data"]["placement"]["availability-zone"]' /run/cloud-init/instance-data.json# Output: us-east-1b
# Get VPC IDsudo jq -r '.ds["meta-data"]["network"]["interfaces"]["macs"][.ds["meta-data"]["mac"]]["vpc-id"]' /run/cloud-init/instance-data.json# Output: vpc-03460bc2910d2b4e6
Why this matters
Section titled “Why this matters”Understanding cloud-init and how to query instance metadata is crucial for:
- Troubleshooting: When instances fail to start correctly, checking user-data and metadata helps identify configuration issues
- Automation: Scripts can use this cached data instead of making API calls, reducing latency and API throttling
- Security: Accessing cached data avoids exposing credentials to the metadata service repeatedly
- Performance: Reading from local files is faster than HTTP requests to the metadata service
Conclusion
Section titled “Conclusion”Cloud-init does more than just run your user-data script. It provides a comprehensive interface to instance metadata that’s invaluable for debugging and automation. Next time you’re troubleshooting an EC2 instance or writing automation scripts, remember these commands - they’ll save you time and API calls.