Get started using Amazon VPC IPAM using the CLI
The following code example shows how to:
Set up and configure Amazon VPC IP Address Manager (IPAM) using the CLI.
Create an IPAM with operating regions (e.g., us-east-1, us-west-2).
Retrieve the private scope ID for the IPAM.
Create a hierarchical structure of IPv4 pools (top-level, regional, and development pools).
Provision CIDR blocks to each pool (e.g., 10.0.0.0/8, 10.0.0.0/16, 10.0.0.0/24).
Create a VPC using a CIDR allocated from an IPAM pool.
Verify IPAM pool allocations and VPC creation.
Troubleshoot common issues like permission errors, CIDR allocation failures, and dependency violations.
Clean up IPAM resources (VPC, pools, CIDRs, and IPAM) to avoid unnecessary charges.
Explore next steps for advanced IPAM features.
- Bash
-
- Amazon CLI with Bash script
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the Sample developer tutorials
repository. #!/bin/bash # IPAM Getting Started CLI Script - Version 7 # This script creates an IPAM, creates a hierarchy of IP address pools, and allocates a CIDR to a VPC # Fixed to correctly identify the private scope ID, wait for resources to be available, add locale to development pool, # use the correct parameter names for VPC creation, and wait for CIDR provisioning to complete # Set up logging LOG_FILE="ipam_script.log" exec > >(tee -a "$LOG_FILE") 2>&1 echo "Starting IPAM setup script at $(date)" echo "All commands and outputs will be logged to $LOG_FILE" # Function to handle errors handle_error() { echo "ERROR: $1" echo "Attempting to clean up resources..." cleanup_resources exit 1 } # Function to clean up resources cleanup_resources() { echo "" echo "===========================================" echo "RESOURCES CREATED:" echo "===========================================" if [ -n "$VPC_ID" ]; then echo "VPC: $VPC_ID" fi if [ -n "$DEV_POOL_ID" ]; then echo "Development Pool: $DEV_POOL_ID" fi if [ -n "$REGIONAL_POOL_ID" ]; then echo "Regional Pool: $REGIONAL_POOL_ID" fi if [ -n "$TOP_POOL_ID" ]; then echo "Top-level Pool: $TOP_POOL_ID" fi if [ -n "$IPAM_ID" ]; then echo "IPAM: $IPAM_ID" fi echo "" echo "===========================================" echo "CLEANUP CONFIRMATION" echo "===========================================" echo "Do you want to clean up all created resources? (y/n): " read -r CLEANUP_CHOICE if [[ "$CLEANUP_CHOICE" =~ ^[Yy]$ ]]; then echo "Starting cleanup..." # Delete resources in reverse order of creation to handle dependencies if [ -n "$VPC_ID" ]; then echo "Deleting VPC: $VPC_ID" aws ec2 delete-vpc --vpc-id "$VPC_ID" || echo "Failed to delete VPC" echo "Waiting for VPC to be deleted..." sleep 10 fi if [ -n "$DEV_POOL_ID" ]; then echo "Deleting Development Pool: $DEV_POOL_ID" # First deprovision any CIDRs from the pool CIDRS=$(aws ec2 get-ipam-pool-cidrs --ipam-pool-id "$DEV_POOL_ID" --query 'IpamPoolCidrs[].Cidr' --output text) for CIDR in $CIDRS; do echo "Deprovisioning CIDR $CIDR from Development Pool" aws ec2 deprovision-ipam-pool-cidr --ipam-pool-id "$DEV_POOL_ID" --cidr "$CIDR" || echo "Failed to deprovision CIDR $CIDR" sleep 5 done aws ec2 delete-ipam-pool --ipam-pool-id "$DEV_POOL_ID" || echo "Failed to delete Development Pool" echo "Waiting for Development Pool to be deleted..." sleep 10 fi if [ -n "$REGIONAL_POOL_ID" ]; then echo "Deleting Regional Pool: $REGIONAL_POOL_ID" # First deprovision any CIDRs from the pool CIDRS=$(aws ec2 get-ipam-pool-cidrs --ipam-pool-id "$REGIONAL_POOL_ID" --query 'IpamPoolCidrs[].Cidr' --output text) for CIDR in $CIDRS; do echo "Deprovisioning CIDR $CIDR from Regional Pool" aws ec2 deprovision-ipam-pool-cidr --ipam-pool-id "$REGIONAL_POOL_ID" --cidr "$CIDR" || echo "Failed to deprovision CIDR $CIDR" sleep 5 done aws ec2 delete-ipam-pool --ipam-pool-id "$REGIONAL_POOL_ID" || echo "Failed to delete Regional Pool" echo "Waiting for Regional Pool to be deleted..." sleep 10 fi if [ -n "$TOP_POOL_ID" ]; then echo "Deleting Top-level Pool: $TOP_POOL_ID" # First deprovision any CIDRs from the pool CIDRS=$(aws ec2 get-ipam-pool-cidrs --ipam-pool-id "$TOP_POOL_ID" --query 'IpamPoolCidrs[].Cidr' --output text) for CIDR in $CIDRS; do echo "Deprovisioning CIDR $CIDR from Top-level Pool" aws ec2 deprovision-ipam-pool-cidr --ipam-pool-id "$TOP_POOL_ID" --cidr "$CIDR" || echo "Failed to deprovision CIDR $CIDR" sleep 5 done aws ec2 delete-ipam-pool --ipam-pool-id "$TOP_POOL_ID" || echo "Failed to delete Top-level Pool" echo "Waiting for Top-level Pool to be deleted..." sleep 10 fi if [ -n "$IPAM_ID" ]; then echo "Deleting IPAM: $IPAM_ID" aws ec2 delete-ipam --ipam-id "$IPAM_ID" || echo "Failed to delete IPAM" fi echo "Cleanup completed." else echo "Cleanup skipped. Resources will remain in your account." fi } # Function to wait for a pool to be in the 'create-complete' state wait_for_pool() { local pool_id=$1 local max_attempts=30 local attempt=1 local state="" echo "Waiting for pool $pool_id to be available..." while [ $attempt -le $max_attempts ]; do state=$(aws ec2 describe-ipam-pools --ipam-pool-ids "$pool_id" --query 'IpamPools[0].State' --output text) if [ "$state" = "create-complete" ]; then echo "Pool $pool_id is now available (state: $state)" return 0 fi echo "Attempt $attempt/$max_attempts: Pool $pool_id is in state: $state. Waiting..." sleep 10 ((attempt++)) done echo "Timed out waiting for pool $pool_id to be available" return 1 } # Function to wait for a CIDR to be fully provisioned wait_for_cidr_provisioning() { local pool_id=$1 local cidr=$2 local max_attempts=30 local attempt=1 local state="" echo "Waiting for CIDR $cidr to be fully provisioned in pool $pool_id..." while [ $attempt -le $max_attempts ]; do state=$(aws ec2 get-ipam-pool-cidrs --ipam-pool-id "$pool_id" --query "IpamPoolCidrs[?Cidr=='$cidr'].State" --output text) if [ "$state" = "provisioned" ]; then echo "CIDR $cidr is now fully provisioned (state: $state)" return 0 fi echo "Attempt $attempt/$max_attempts: CIDR $cidr is in state: $state. Waiting..." sleep 10 ((attempt++)) done echo "Timed out waiting for CIDR $cidr to be provisioned" return 1 } # Step 1: Create an IPAM echo "Creating IPAM..." IPAM_RESULT=$(aws ec2 create-ipam \ --description "My IPAM" \ --operating-regions RegionName=us-east-1 RegionName=us-west-2) if [ $? -ne 0 ]; then handle_error "Failed to create IPAM" fi IPAM_ID=$(echo "$IPAM_RESULT" | grep -o '"IpamId": "[^"]*' | cut -d'"' -f4) echo "IPAM created with ID: $IPAM_ID" # Wait for IPAM to be created and available echo "Waiting for IPAM to be available..." sleep 20 # Step 2: Get the IPAM Scope ID - FIXED to correctly identify the private scope echo "Getting IPAM Scope ID..." SCOPE_RESULT=$(aws ec2 describe-ipams --ipam-id "$IPAM_ID") if [ $? -ne 0 ]; then handle_error "Failed to get IPAM details" fi # Extract the private scope ID directly from the IPAM details PRIVATE_SCOPE_ID=$(echo "$SCOPE_RESULT" | grep -o '"PrivateDefaultScopeId": "[^"]*' | cut -d'"' -f4) echo "Private Scope ID: $PRIVATE_SCOPE_ID" if [ -z "$PRIVATE_SCOPE_ID" ]; then handle_error "Failed to get Private Scope ID" fi # Step 3: Create a Top-Level IPv4 Pool echo "Creating Top-level IPv4 Pool..." TOP_POOL_RESULT=$(aws ec2 create-ipam-pool \ --ipam-scope-id "$PRIVATE_SCOPE_ID" \ --address-family ipv4 \ --description "Top-level pool") if [ $? -ne 0 ]; then handle_error "Failed to create Top-level Pool" fi TOP_POOL_ID=$(echo "$TOP_POOL_RESULT" | grep -o '"IpamPoolId": "[^"]*' | cut -d'"' -f4) echo "Top-level Pool created with ID: $TOP_POOL_ID" # Wait for the top-level pool to be available if ! wait_for_pool "$TOP_POOL_ID"; then handle_error "Top-level Pool did not become available in time" fi # Provision CIDR to the top-level pool echo "Provisioning CIDR to Top-level Pool..." TOP_POOL_CIDR="10.0.0.0/8" PROVISION_RESULT=$(aws ec2 provision-ipam-pool-cidr \ --ipam-pool-id "$TOP_POOL_ID" \ --cidr "$TOP_POOL_CIDR") if [ $? -ne 0 ]; then handle_error "Failed to provision CIDR to Top-level Pool" fi echo "$PROVISION_RESULT" # Wait for the CIDR to be fully provisioned if ! wait_for_cidr_provisioning "$TOP_POOL_ID" "$TOP_POOL_CIDR"; then handle_error "CIDR provisioning to Top-level Pool did not complete in time" fi # Step 4: Create a Regional IPv4 Pool echo "Creating Regional IPv4 Pool..." REGIONAL_POOL_RESULT=$(aws ec2 create-ipam-pool \ --ipam-scope-id "$PRIVATE_SCOPE_ID" \ --source-ipam-pool-id "$TOP_POOL_ID" \ --locale us-east-1 \ --address-family ipv4 \ --description "Regional pool in us-east-1") if [ $? -ne 0 ]; then handle_error "Failed to create Regional Pool" fi REGIONAL_POOL_ID=$(echo "$REGIONAL_POOL_RESULT" | grep -o '"IpamPoolId": "[^"]*' | cut -d'"' -f4) echo "Regional Pool created with ID: $REGIONAL_POOL_ID" # Wait for the regional pool to be available if ! wait_for_pool "$REGIONAL_POOL_ID"; then handle_error "Regional Pool did not become available in time" fi # Provision CIDR to the regional pool echo "Provisioning CIDR to Regional Pool..." REGIONAL_POOL_CIDR="10.0.0.0/16" PROVISION_RESULT=$(aws ec2 provision-ipam-pool-cidr \ --ipam-pool-id "$REGIONAL_POOL_ID" \ --cidr "$REGIONAL_POOL_CIDR") if [ $? -ne 0 ]; then handle_error "Failed to provision CIDR to Regional Pool" fi echo "$PROVISION_RESULT" # Wait for the CIDR to be fully provisioned if ! wait_for_cidr_provisioning "$REGIONAL_POOL_ID" "$REGIONAL_POOL_CIDR"; then handle_error "CIDR provisioning to Regional Pool did not complete in time" fi # Step 5: Create a Development IPv4 Pool - FIXED to include locale echo "Creating Development IPv4 Pool..." DEV_POOL_RESULT=$(aws ec2 create-ipam-pool \ --ipam-scope-id "$PRIVATE_SCOPE_ID" \ --source-ipam-pool-id "$REGIONAL_POOL_ID" \ --locale us-east-1 \ --address-family ipv4 \ --description "Development pool") if [ $? -ne 0 ]; then handle_error "Failed to create Development Pool" fi DEV_POOL_ID=$(echo "$DEV_POOL_RESULT" | grep -o '"IpamPoolId": "[^"]*' | cut -d'"' -f4) echo "Development Pool created with ID: $DEV_POOL_ID" # Wait for the development pool to be available if ! wait_for_pool "$DEV_POOL_ID"; then handle_error "Development Pool did not become available in time" fi # Provision CIDR to the development pool echo "Provisioning CIDR to Development Pool..." DEV_POOL_CIDR="10.0.0.0/24" PROVISION_RESULT=$(aws ec2 provision-ipam-pool-cidr \ --ipam-pool-id "$DEV_POOL_ID" \ --cidr "$DEV_POOL_CIDR") if [ $? -ne 0 ]; then handle_error "Failed to provision CIDR to Development Pool" fi echo "$PROVISION_RESULT" # Wait for the CIDR to be fully provisioned if ! wait_for_cidr_provisioning "$DEV_POOL_ID" "$DEV_POOL_CIDR"; then handle_error "CIDR provisioning to Development Pool did not complete in time" fi # Step 6: Create a VPC Using an IPAM Pool CIDR - FIXED to use the correct parameter names and a smaller netmask length echo "Creating VPC using IPAM Pool CIDR..." VPC_RESULT=$(aws ec2 create-vpc \ --ipv4-ipam-pool-id "$DEV_POOL_ID" \ --ipv4-netmask-length 26 \ --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=IPAM-VPC}]') if [ $? -ne 0 ]; then handle_error "Failed to create VPC" fi VPC_ID=$(echo "$VPC_RESULT" | grep -o '"VpcId": "[^"]*' | cut -d'"' -f4) echo "VPC created with ID: $VPC_ID" # Step 7: Verify the IPAM Pool Allocation echo "Verifying IPAM Pool Allocation..." ALLOCATION_RESULT=$(aws ec2 get-ipam-pool-allocations \ --ipam-pool-id "$DEV_POOL_ID") if [ $? -ne 0 ]; then handle_error "Failed to verify IPAM Pool Allocation" fi echo "IPAM Pool Allocation verified:" echo "$ALLOCATION_RESULT" | grep -A 5 "Allocations" echo "" echo "IPAM setup completed successfully!" echo "" # Prompt for cleanup cleanup_resources echo "Script completed at $(date)" exit 0
-
For API details, see the following topics in Amazon CLI Command Reference.
-
For a complete list of Amazon SDK developer guides and code examples, see Create Amazon EC2 resources using an Amazon SDK. This topic also includes information about getting started and details about previous SDK versions.