View a markdown version of this page

Creating an Amazon RDS DB instance - Amazon Elastic Compute Cloud
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Creating an Amazon RDS DB instance

The following code example shows how to:

  • Set up networking components

  • Create a DB subnet group

  • Create a DB instance

  • Clean up resources

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 # Script to create an Amazon RDS DB instance # This script follows the tutorial at https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html # Set up logging LOG_FILE="rds_creation_$(date +%Y%m%d_%H%M%S).log" exec > >(tee -a "$LOG_FILE") 2>&1 echo "Starting RDS DB instance creation script - $(date)" echo "All actions will be logged to $LOG_FILE" echo "==============================================" # Function to check for errors in command output check_error() { local output=$1 local cmd=$2 if echo "$output" | grep -i "error" > /dev/null; then echo "ERROR: Command failed: $cmd" echo "$output" cleanup_on_error exit 1 fi } # Function to clean up resources on error cleanup_on_error() { echo "Error encountered. Attempting to clean up resources..." if [ -n "$DB_INSTANCE_ID" ]; then echo "Deleting DB instance $DB_INSTANCE_ID..." aws rds delete-db-instance --db-instance-identifier "$DB_INSTANCE_ID" --skip-final-snapshot echo "Waiting for DB instance to be deleted..." aws rds wait db-instance-deleted --db-instance-identifier "$DB_INSTANCE_ID" fi if [ -n "$DB_SUBNET_GROUP_NAME" ] && [ "$CREATED_SUBNET_GROUP" = "true" ]; then echo "Deleting DB subnet group $DB_SUBNET_GROUP_NAME..." aws rds delete-db-subnet-group --db-subnet-group-name "$DB_SUBNET_GROUP_NAME" fi if [ -n "$SECURITY_GROUP_ID" ] && [ "$CREATED_SECURITY_GROUP" = "true" ]; then echo "Deleting security group $SECURITY_GROUP_ID..." aws ec2 delete-security-group --group-id "$SECURITY_GROUP_ID" fi echo "Cleanup completed." } # Generate a random identifier for resources RANDOM_ID=$(openssl rand -hex 4) DB_INSTANCE_ID="mydb-${RANDOM_ID}" DB_SUBNET_GROUP_NAME="mydbsubnet-${RANDOM_ID}" SECURITY_GROUP_NAME="mydbsg-${RANDOM_ID}" # Track created resources CREATED_SECURITY_GROUP="false" CREATED_SUBNET_GROUP="false" # Array to store created resources for display declare -a CREATED_RESOURCES echo "Step 1: Checking for default VPC..." VPC_OUTPUT=$(aws ec2 describe-vpcs --filters "Name=isDefault,Values=true") check_error "$VPC_OUTPUT" "aws ec2 describe-vpcs" # Extract VPC ID VPC_ID=$(echo "$VPC_OUTPUT" | grep -o '"VpcId": "[^"]*' | cut -d'"' -f4) if [ -z "$VPC_ID" ]; then echo "No default VPC found. Please create a VPC before running this script." exit 1 fi echo "Using VPC: $VPC_ID" echo "Step 2: Getting subnets from the VPC..." SUBNET_OUTPUT=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPC_ID") check_error "$SUBNET_OUTPUT" "aws ec2 describe-subnets" # Extract subnet IDs (we need at least 2 in different AZs) SUBNET_IDS=($(echo "$SUBNET_OUTPUT" | grep -o '"SubnetId": "[^"]*' | cut -d'"' -f4)) if [ ${#SUBNET_IDS[@]} -lt 2 ]; then echo "Error: Need at least 2 subnets in different AZs. Found ${#SUBNET_IDS[@]} subnets." exit 1 fi echo "Found ${#SUBNET_IDS[@]} subnets: ${SUBNET_IDS[*]}" echo "Step 3: Creating security group for RDS..." SG_OUTPUT=$(aws ec2 create-security-group \ --group-name "$SECURITY_GROUP_NAME" \ --description "Security group for RDS database access" \ --vpc-id "$VPC_ID") check_error "$SG_OUTPUT" "aws ec2 create-security-group" SECURITY_GROUP_ID=$(echo "$SG_OUTPUT" | grep -o '"GroupId": "[^"]*' | cut -d'"' -f4) CREATED_SECURITY_GROUP="true" CREATED_RESOURCES+=("Security Group: $SECURITY_GROUP_ID ($SECURITY_GROUP_NAME)") echo "Created security group: $SECURITY_GROUP_ID" echo "Step 4: Adding inbound rule to security group..." # Note: In a production environment, you should restrict this to specific IP ranges # We're using the local machine's IP address for this example MY_IP=$(curl -s https://checkip.amazonaws.com) check_error "$MY_IP" "curl -s https://checkip.amazonaws.com" INGRESS_OUTPUT=$(aws ec2 authorize-security-group-ingress \ --group-id "$SECURITY_GROUP_ID" \ --protocol tcp \ --port 3306 \ --cidr "${MY_IP}/32") check_error "$INGRESS_OUTPUT" "aws ec2 authorize-security-group-ingress" echo "Added inbound rule to allow MySQL connections from ${MY_IP}/32" echo "Step 5: Creating DB subnet group..." # Select the first two subnets for the DB subnet group SUBNET1=${SUBNET_IDS[0]} SUBNET2=${SUBNET_IDS[1]} SUBNET_GROUP_OUTPUT=$(aws rds create-db-subnet-group \ --db-subnet-group-name "$DB_SUBNET_GROUP_NAME" \ --db-subnet-group-description "Subnet group for RDS tutorial" \ --subnet-ids "$SUBNET1" "$SUBNET2") check_error "$SUBNET_GROUP_OUTPUT" "aws rds create-db-subnet-group" CREATED_SUBNET_GROUP="true" CREATED_RESOURCES+=("DB Subnet Group: $DB_SUBNET_GROUP_NAME") echo "Created DB subnet group: $DB_SUBNET_GROUP_NAME" echo "Step 6: Creating a secure password in AWS Secrets Manager..." SECRET_NAME="rds-db-credentials-${RANDOM_ID}" SECRET_OUTPUT=$(aws secretsmanager create-secret \ --name "$SECRET_NAME" \ --description "RDS DB credentials for $DB_INSTANCE_ID" \ --secret-string '{"username":"adminuser","password":"'"$(openssl rand -base64 16)"'"}') check_error "$SECRET_OUTPUT" "aws secretsmanager create-secret" SECRET_ARN=$(echo "$SECRET_OUTPUT" | grep -o '"ARN": "[^"]*' | cut -d'"' -f4) CREATED_RESOURCES+=("Secret: $SECRET_ARN ($SECRET_NAME)") echo "Created secret: $SECRET_NAME" echo "Step 7: Retrieving the username and password from the secret..." SECRET_VALUE_OUTPUT=$(aws secretsmanager get-secret-value --secret-id "$SECRET_NAME" --query 'SecretString' --output text) check_error "$SECRET_VALUE_OUTPUT" "aws secretsmanager get-secret-value" DB_USERNAME=$(echo "$SECRET_VALUE_OUTPUT" | grep -o '"username":"[^"]*' | cut -d'"' -f4) DB_PASSWORD=$(echo "$SECRET_VALUE_OUTPUT" | grep -o '"password":"[^"]*' | cut -d'"' -f4) echo "Retrieved database credentials" echo "Step 8: Creating RDS DB instance..." echo "This may take several minutes..." DB_OUTPUT=$(aws rds create-db-instance \ --db-instance-identifier "$DB_INSTANCE_ID" \ --db-instance-class db.t3.micro \ --engine mysql \ --master-username "$DB_USERNAME" \ --master-user-password "$DB_PASSWORD" \ --allocated-storage 20 \ --vpc-security-group-ids "$SECURITY_GROUP_ID" \ --db-subnet-group-name "$DB_SUBNET_GROUP_NAME" \ --backup-retention-period 7 \ --no-publicly-accessible \ --no-multi-az) check_error "$DB_OUTPUT" "aws rds create-db-instance" CREATED_RESOURCES+=("DB Instance: $DB_INSTANCE_ID") echo "DB instance creation initiated: $DB_INSTANCE_ID" echo "Waiting for DB instance to become available..." echo "This may take 5-10 minutes..." aws rds wait db-instance-available --db-instance-identifier "$DB_INSTANCE_ID" DB_STATUS=$? if [ $DB_STATUS -ne 0 ]; then echo "Error waiting for DB instance to become available" cleanup_on_error exit 1 fi echo "DB instance is now available!" echo "Step 9: Getting connection information..." ENDPOINT_INFO=$(aws rds describe-db-instances \ --db-instance-identifier "$DB_INSTANCE_ID" \ --query 'DBInstances[0].[Endpoint.Address,Endpoint.Port,MasterUsername]' \ --output text) check_error "$ENDPOINT_INFO" "aws rds describe-db-instances" DB_ENDPOINT=$(echo "$ENDPOINT_INFO" | awk '{print $1}') DB_PORT=$(echo "$ENDPOINT_INFO" | awk '{print $2}') DB_USER=$(echo "$ENDPOINT_INFO" | awk '{print $3}') echo "==============================================" echo "DB Instance successfully created!" echo "==============================================" echo "Connection Information:" echo " Endpoint: $DB_ENDPOINT" echo " Port: $DB_PORT" echo " Username: $DB_USER" echo " Password: [Stored in AWS Secrets Manager - $SECRET_NAME]" echo "" echo "To connect using the mysql client:" echo "mysql -h $DB_ENDPOINT -P $DB_PORT -u $DB_USER -p" echo "==============================================" echo "" echo "Resources created:" for resource in "${CREATED_RESOURCES[@]}"; do echo " - $resource" done echo "" # Ask user if they want to clean up resources 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 process..." echo "Step 1: Deleting DB instance $DB_INSTANCE_ID..." aws rds delete-db-instance --db-instance-identifier "$DB_INSTANCE_ID" --skip-final-snapshot echo "Waiting for DB instance to be deleted..." aws rds wait db-instance-deleted --db-instance-identifier "$DB_INSTANCE_ID" echo "Step 2: Deleting secret $SECRET_NAME..." aws secretsmanager delete-secret --secret-id "$SECRET_NAME" --force-delete-without-recovery echo "Step 3: Deleting DB subnet group $DB_SUBNET_GROUP_NAME..." aws rds delete-db-subnet-group --db-subnet-group-name "$DB_SUBNET_GROUP_NAME" echo "Step 4: Deleting security group $SECURITY_GROUP_ID..." aws ec2 delete-security-group --group-id "$SECURITY_GROUP_ID" echo "Cleanup completed successfully!" else echo "Skipping cleanup. Resources will remain in your AWS account." echo "To clean up later, you'll need to delete these resources manually." fi echo "Script completed successfully!"

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.