기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
Amazon DocumentDB 시작하기
다음 코드 예제에서는 다음과 같은 작업을 수행하는 방법을 보여줍니다.
DB 서브넷 그룹 만들기
DocumentDB 클러스터 생성
DocumentDB 인스턴스 생성
보안 및 연결 구성
리소스 정리
- Bash
-
- AWS CLI Bash 스크립트 사용
-
참고
GitHub에 더 많은 내용이 있습니다. 샘플 개발자 튜토리얼
리포지토리에서 전체 예제를 찾아보고 설정 및 실행 방법을 배워보세요. #!/bin/bash # Amazon DocumentDB - Getting Started # This script creates a DocumentDB cluster with encrypted storage, stores the # master password in Secrets Manager, and displays connection information. set -eE ############################################################################### # Configuration ############################################################################### SUFFIX=$(LC_ALL=C tr -dc 'a-z0-9' </dev/urandom | head -c 8) CLUSTER_ID="docdb-gs-${SUFFIX}" INSTANCE_ID="${CLUSTER_ID}-inst" SUBNET_GROUP_NAME="docdb-subnet-${SUFFIX}" SECRET_NAME="docdb-secret-${SUFFIX}" MASTER_USER="docdbadmin" ENGINE_VERSION="5.0.0" INSTANCE_CLASS="db.t3.medium" DOCDB_PORT=27017 WAIT_TIMEOUT=900 TEMP_DIR=$(mktemp -d) LOG_FILE="${TEMP_DIR}/documentdb-gs.log" trap 'rm -rf "$TEMP_DIR"' EXIT CREATED_RESOURCES=() ############################################################################### # Logging ############################################################################### exec > >(tee -a "$LOG_FILE") 2>&1 echo "Log file: $LOG_FILE" echo "" ############################################################################### # Region pre-check ############################################################################### CONFIGURED_REGION=$(aws configure get region 2>/dev/null || true) if [ -z "$CONFIGURED_REGION" ] && [ -z "$AWS_DEFAULT_REGION" ] && [ -z "$AWS_REGION" ]; then echo "ERROR: No AWS region configured." echo "Run 'aws configure set region <region>' or export AWS_DEFAULT_REGION." exit 1 fi REGION="${AWS_REGION:-${AWS_DEFAULT_REGION:-$CONFIGURED_REGION}}" echo "Using region: $REGION" echo "" ############################################################################### # Error handler ############################################################################### handle_error() { echo "" echo "===========================================" echo "ERROR at $1" echo "===========================================" echo "" if [ ${#CREATED_RESOURCES[@]} -gt 0 ]; then echo "Resources created before error:" for r in "${CREATED_RESOURCES[@]}"; do echo " - $r" done echo "" echo "Attempting cleanup..." cleanup_resources fi exit 1 } trap 'handle_error "line $LINENO"' ERR ############################################################################### # Wait function ############################################################################### wait_for_status() { local resource_type="$1" local resource_id="$2" local target_status="$3" local timeout="${4:-$WAIT_TIMEOUT}" local elapsed=0 local interval=30 echo "Waiting for $resource_type '$resource_id' to reach '$target_status'..." while true; do local current_status="" if [ "$resource_type" = "cluster" ]; then current_status=$(aws docdb describe-db-clusters \ --db-cluster-identifier "$resource_id" \ --query "DBClusters[0].Status" --output text 2>&1) elif [ "$resource_type" = "instance" ]; then current_status=$(aws docdb describe-db-instances \ --db-instance-identifier "$resource_id" \ --query "DBInstances[0].DBInstanceStatus" --output text 2>&1) fi if echo "$current_status" | grep -iq "error"; then echo "ERROR checking status: $current_status" return 1 fi echo " Status: $current_status ($elapsed/${timeout}s)" if [ "$current_status" = "$target_status" ]; then echo " $resource_type '$resource_id' is now '$target_status'." return 0 fi if [ "$elapsed" -ge "$timeout" ]; then echo "ERROR: Timed out after ${timeout}s waiting for $resource_type '$resource_id'." return 1 fi sleep "$interval" elapsed=$((elapsed + interval)) done } ############################################################################### # Wait for deletion ############################################################################### wait_for_deletion() { local resource_type="$1" local resource_id="$2" local timeout="${3:-$WAIT_TIMEOUT}" local elapsed=0 local interval=30 echo "Waiting for $resource_type '$resource_id' to be deleted..." while true; do local result="" if [ "$resource_type" = "cluster" ]; then result=$(aws docdb describe-db-clusters \ --db-cluster-identifier "$resource_id" \ --query "DBClusters[0].Status" --output text 2>&1) || true elif [ "$resource_type" = "instance" ]; then result=$(aws docdb describe-db-instances \ --db-instance-identifier "$resource_id" \ --query "DBInstances[0].DBInstanceStatus" --output text 2>&1) || true fi if echo "$result" | grep -iq "DBClusterNotFoundFault\|DBInstanceNotFound\|not found"; then echo " $resource_type '$resource_id' deleted." return 0 fi echo " Still deleting... ($elapsed/${timeout}s)" if [ "$elapsed" -ge "$timeout" ]; then echo "WARNING: Timed out waiting for $resource_type '$resource_id' deletion." return 1 fi sleep "$interval" elapsed=$((elapsed + interval)) done } ############################################################################### # Cleanup ############################################################################### cleanup_resources() { echo "" echo "Cleaning up resources..." echo "" # Revoke security group ingress rule if [ -n "${SG_ID:-}" ] && [ -n "${MY_IP:-}" ]; then echo "Revoking security group ingress rule..." aws ec2 revoke-security-group-ingress \ --group-id "$SG_ID" \ --protocol tcp \ --port "$DOCDB_PORT" \ --cidr "${MY_IP}/32" 2>&1 || echo "WARNING: Failed to revoke SG ingress rule." fi # Delete instance (must be deleted before cluster) if printf '%s\n' "${CREATED_RESOURCES[@]}" | grep -q "instance:"; then echo "Deleting instance '${INSTANCE_ID}'..." aws docdb delete-db-instance \ --db-instance-identifier "$INSTANCE_ID" 2>&1 || echo "WARNING: Failed to delete instance." wait_for_deletion "instance" "$INSTANCE_ID" || true fi # Delete cluster (skip final snapshot) if printf '%s\n' "${CREATED_RESOURCES[@]}" | grep -q "cluster:"; then echo "Deleting cluster '${CLUSTER_ID}'..." aws docdb delete-db-cluster \ --db-cluster-identifier "$CLUSTER_ID" \ --skip-final-snapshot 2>&1 || echo "WARNING: Failed to delete cluster." wait_for_deletion "cluster" "$CLUSTER_ID" || true fi # Delete subnet group (must wait for cluster deletion) if printf '%s\n' "${CREATED_RESOURCES[@]}" | grep -q "subnet-group:"; then echo "Deleting subnet group '${SUBNET_GROUP_NAME}'..." aws docdb delete-db-subnet-group \ --db-subnet-group-name "$SUBNET_GROUP_NAME" 2>&1 || echo "WARNING: Failed to delete subnet group." fi # Delete secret with scheduled deletion instead of immediate deletion if printf '%s\n' "${CREATED_RESOURCES[@]}" | grep -q "secret:"; then echo "Deleting secret '${SECRET_NAME}' (scheduled for 7 days)..." aws secretsmanager delete-secret \ --secret-id "$SECRET_NAME" \ --recovery-window-in-days 7 2>&1 || echo "WARNING: Failed to delete secret." fi echo "" echo "Cleanup complete." } ############################################################################### # Step 1: Generate password and store in Secrets Manager ############################################################################### echo "===========================================" echo "Step 1: Create master password in Secrets Manager" echo "===========================================" echo "" # Generate a strong password using openssl for better randomness # Meets DocumentDB requirements: 8-100 chars, alphanumeric + special chars MASTER_PASSWORD=$(openssl rand -base64 32 | tr -d '/' | cut -c1-20) # Securely store password in temporary file with restricted permissions TEMP_PASS_FILE=$(mktemp) chmod 600 "$TEMP_PASS_FILE" echo -n "$MASTER_PASSWORD" > "$TEMP_PASS_FILE" trap "rm -f '$TEMP_PASS_FILE'; rm -rf '$TEMP_DIR'" EXIT SECRET_OUTPUT=$(aws secretsmanager create-secret \ --name "$SECRET_NAME" \ --description "DocumentDB master password for ${CLUSTER_ID}" \ --secret-string file://"$TEMP_PASS_FILE" \ --tags Key=project,Value=doc-smith Key=tutorial,Value=documentdb-gs \ --output text --query "ARN" 2>&1) # Securely clear password from memory MASTER_PASSWORD="" if echo "$SECRET_OUTPUT" | grep -iq "error"; then echo "ERROR creating secret: $SECRET_OUTPUT" exit 1 fi SECRET_ARN="$SECRET_OUTPUT" CREATED_RESOURCES+=("secret:${SECRET_NAME}") echo "Secret created: $SECRET_NAME" echo "Secret ARN: $SECRET_ARN" echo "" ############################################################################### # Step 2: Find default VPC and subnets ############################################################################### echo "===========================================" echo "Step 2: Find default VPC and subnets" echo "===========================================" echo "" VPC_ID=$(aws ec2 describe-vpcs \ --filters "Name=isDefault,Values=true" \ --query "Vpcs[0].VpcId" --output text 2>&1) if echo "$VPC_ID" | grep -iq "error"; then echo "ERROR finding default VPC: $VPC_ID" exit 1 fi if [ "$VPC_ID" = "None" ] || [ -z "$VPC_ID" ]; then echo "ERROR: No default VPC found. Create one with 'aws ec2 create-default-vpc'." exit 1 fi echo "Default VPC: $VPC_ID" # Get subnets in at least 2 different AZs (space-separated) SUBNET_INFO=$(aws ec2 describe-subnets \ --filters "Name=vpc-id,Values=${VPC_ID}" "Name=default-for-az,Values=true" \ --query "Subnets[*].[SubnetId,AvailabilityZone]" --output text 2>&1) if echo "$SUBNET_INFO" | grep -iq "error"; then echo "ERROR finding subnets: $SUBNET_INFO" exit 1 fi # Collect unique AZs and their subnet IDs declare -A AZ_SUBNETS while IFS=$'\t' read -r sid az; do if [ -z "${AZ_SUBNETS[$az]+x}" ]; then AZ_SUBNETS[$az]="$sid" fi done <<< "$SUBNET_INFO" AZ_COUNT=${#AZ_SUBNETS[@]} if [ "$AZ_COUNT" -lt 2 ]; then echo "ERROR: DocumentDB requires subnets in at least 2 AZs. Found $AZ_COUNT." exit 1 fi # Build space-separated subnet ID list SUBNET_IDS="" for az in "${!AZ_SUBNETS[@]}"; do if [ -n "$SUBNET_IDS" ]; then SUBNET_IDS="${SUBNET_IDS} ${AZ_SUBNETS[$az]}" else SUBNET_IDS="${AZ_SUBNETS[$az]}" fi done echo "Subnets (${AZ_COUNT} AZs): $SUBNET_IDS" echo "" ############################################################################### # Step 3: Create subnet group ############################################################################### echo "===========================================" echo "Step 3: Create DocumentDB subnet group" echo "===========================================" echo "" SUBNET_GROUP_OUTPUT=$(aws docdb create-db-subnet-group \ --db-subnet-group-name "$SUBNET_GROUP_NAME" \ --db-subnet-group-description "Subnet group for DocumentDB getting started" \ --subnet-ids $SUBNET_IDS \ --tags Key=project,Value=doc-smith Key=tutorial,Value=documentdb-gs \ --query "DBSubnetGroup.DBSubnetGroupName" --output text 2>&1) if echo "$SUBNET_GROUP_OUTPUT" | grep -iq "error"; then echo "ERROR creating subnet group: $SUBNET_GROUP_OUTPUT" exit 1 fi CREATED_RESOURCES+=("subnet-group:${SUBNET_GROUP_NAME}") echo "Subnet group created: $SUBNET_GROUP_NAME" echo "" ############################################################################### # Step 4: Create DocumentDB cluster ############################################################################### echo "===========================================" echo "Step 4: Create DocumentDB cluster" echo "===========================================" echo "" # Read password securely from file for cluster creation MASTER_PASSWORD=$(cat "$TEMP_PASS_FILE") CLUSTER_OUTPUT=$(aws docdb create-db-cluster \ --db-cluster-identifier "$CLUSTER_ID" \ --engine docdb \ --engine-version "$ENGINE_VERSION" \ --master-username "$MASTER_USER" \ --master-user-password "$MASTER_PASSWORD" \ --db-subnet-group-name "$SUBNET_GROUP_NAME" \ --storage-encrypted \ --kms-key-id "alias/aws/docdb" \ --no-deletion-protection \ --enable-cloudwatch-logs-exports '["audit","error","general","slowquery"]' \ --tags Key=project,Value=doc-smith Key=tutorial,Value=documentdb-gs \ --query "DBCluster.DBClusterIdentifier" --output text 2>&1) # Clear password immediately after use MASTER_PASSWORD="" if echo "$CLUSTER_OUTPUT" | grep -iq "error"; then echo "ERROR creating cluster: $CLUSTER_OUTPUT" exit 1 fi CREATED_RESOURCES+=("cluster:${CLUSTER_ID}") echo "Cluster created: $CLUSTER_ID" echo "" wait_for_status "cluster" "$CLUSTER_ID" "available" echo "" ############################################################################### # Step 5: Create DocumentDB instance ############################################################################### echo "===========================================" echo "Step 5: Create DocumentDB instance" echo "===========================================" echo "" INSTANCE_OUTPUT=$(aws docdb create-db-instance \ --db-instance-identifier "$INSTANCE_ID" \ --db-instance-class "$INSTANCE_CLASS" \ --db-cluster-identifier "$CLUSTER_ID" \ --engine docdb \ --tags Key=project,Value=doc-smith Key=tutorial,Value=documentdb-gs \ --query "DBInstance.DBInstanceIdentifier" --output text 2>&1) if echo "$INSTANCE_OUTPUT" | grep -iq "error"; then echo "ERROR creating instance: $INSTANCE_OUTPUT" exit 1 fi CREATED_RESOURCES+=("instance:${INSTANCE_ID}") echo "Instance created: $INSTANCE_ID" echo "" wait_for_status "instance" "$INSTANCE_ID" "available" echo "" ############################################################################### # Step 6: Get cluster endpoint and security group ############################################################################### echo "===========================================" echo "Step 6: Get cluster endpoint and security group" echo "===========================================" echo "" CLUSTER_DETAILS=$(aws docdb describe-db-clusters \ --db-cluster-identifier "$CLUSTER_ID" \ --query "DBClusters[0].[Endpoint,VpcSecurityGroups[0].VpcSecurityGroupId]" \ --output text 2>&1) if echo "$CLUSTER_DETAILS" | grep -iq "error"; then echo "ERROR getting cluster details: $CLUSTER_DETAILS" exit 1 fi CLUSTER_ENDPOINT=$(echo "$CLUSTER_DETAILS" | awk '{print $1}') SG_ID=$(echo "$CLUSTER_DETAILS" | awk '{print $2}') echo "Cluster endpoint: $CLUSTER_ENDPOINT" echo "Security group: $SG_ID" echo "" ############################################################################### # Step 7: Add security group ingress for port 27017 from user's IP ############################################################################### echo "===========================================" echo "Step 7: Add security group ingress rule" echo "===========================================" echo "" # Get the user's public IP with timeout and error handling MY_IP=$(timeout 5 curl -s --max-time 5 https://checkip.amazonaws.com 2>/dev/null || true) if [ -z "$MY_IP" ] || echo "$MY_IP" | grep -iq "error\|could not\|failed"; then echo "WARNING: Could not determine public IP address. Skipping security group rule." echo "You must manually add an ingress rule for your IP to security group $SG_ID" MY_IP="" else # Trim whitespace MY_IP=$(echo "$MY_IP" | tr -d '[:space:]') # Validate IP format (basic check) if ! echo "$MY_IP" | grep -qE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'; then echo "WARNING: Invalid IP address format: $MY_IP. Skipping security group rule." MY_IP="" else echo "Your public IP: $MY_IP" SG_RULE_OUTPUT=$(aws ec2 authorize-security-group-ingress \ --group-id "$SG_ID" \ --protocol tcp \ --port "$DOCDB_PORT" \ --cidr "${MY_IP}/32" 2>&1) if echo "$SG_RULE_OUTPUT" | grep -iq "error"; then # Ignore if rule already exists if echo "$SG_RULE_OUTPUT" | grep -iq "Duplicate"; then echo "Ingress rule already exists." else echo "ERROR adding ingress rule: $SG_RULE_OUTPUT" exit 1 fi else echo "Ingress rule added: TCP ${DOCDB_PORT} from ${MY_IP}/32" CREATED_RESOURCES+=("sg-rule:${SG_ID}:${MY_IP}") fi fi fi echo "" ############################################################################### # Step 8: Download CA certificate ############################################################################### echo "===========================================" echo "Step 8: Download Amazon DocumentDB CA certificate" echo "===========================================" echo "" CA_CERT_PATH="${TEMP_DIR}/global-bundle.pem" CA_CERT_URL="https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem" if timeout 10 curl -s --max-time 10 -o "$CA_CERT_PATH" "$CA_CERT_URL" 2>&1; then if [ -s "$CA_CERT_PATH" ]; then # Verify it's a valid PEM file and check file permissions if grep -q "BEGIN CERTIFICATE" "$CA_CERT_PATH"; then chmod 644 "$CA_CERT_PATH" echo "CA certificate downloaded to: $CA_CERT_PATH" else echo "WARNING: Downloaded file is not a valid PEM certificate." CA_CERT_PATH="" fi else echo "WARNING: Failed to download CA certificate (empty file)." CA_CERT_PATH="" fi else echo "WARNING: Failed to download CA certificate (timeout or network error)." CA_CERT_PATH="" fi echo "" ############################################################################### # Step 9: Display connection information ############################################################################### echo "===========================================" echo "CONNECTION INFORMATION" echo "===========================================" echo "" echo "Cluster endpoint : $CLUSTER_ENDPOINT" echo "Port : $DOCDB_PORT" echo "Master username : $MASTER_USER" echo "Secret name : $SECRET_NAME (contains password)" echo "Security group : $SG_ID" if [ -n "$CA_CERT_PATH" ]; then echo "CA certificate : $CA_CERT_PATH" fi echo "" echo "To connect with mongosh:" if [ -n "$CA_CERT_PATH" ]; then echo " mongosh --tls --host ${CLUSTER_ENDPOINT} --tlsCAFile ${CA_CERT_PATH} \\" else echo " mongosh --tls --host ${CLUSTER_ENDPOINT} \\" fi echo " --retryWrites false --username ${MASTER_USER} --password \$(aws secretsmanager get-secret-value --secret-id ${SECRET_NAME} --query SecretString --output text)" echo "" ############################################################################### # Step 10: Cleanup ############################################################################### echo "" echo "===========================================" echo "CLEANUP CONFIRMATION" echo "===========================================" echo "" echo "Resources created:" for r in "${CREATED_RESOURCES[@]}"; do echo " - $r" done echo "" echo "Automatically cleaning up all created resources..." echo "" cleanup_resources echo "Done."-
API 세부 정보는 AWS CLI 명령 참조의 다음 토픽을 참조하세요.
-
AWS SDK 개발자 안내서 및 코드 예제의 전체 목록은 섹션을 참조하세요AWS SDK를 사용하여 Amazon EC2 리소스 생성. 이 주제에는 시작하기에 대한 정보와 이전 SDK 버전에 대한 세부 정보도 포함되어 있습니다.
Marketplace 구매자 시작하기
Amazon EC2 시작하기