View a markdown version of this page

사용자 지정 속성과 함께 Cloud Map 서비스 검색 사용 - AWS SDK 코드 예제

Doc AWS SDK 예제 GitHub 리포지토리에서 더 많은 SDK 예제를 사용할 수 있습니다. AWS

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

사용자 지정 속성과 함께 Cloud Map 서비스 검색 사용

다음 코드 예제에서는 다음과 같은 작업을 수행하는 방법을 보여줍니다.

  • Cloud Map 네임스페이스 생성

  • DynamoDB 테이블 생성

  • Cloud Map 데이터 서비스 생성 및 DynamoDB 테이블 등록

  • Lambda 함수에 대한 IAM 역할 생성

  • Lambda 함수를 생성하여 데이터 쓰기

  • Cloud Map 앱 서비스 생성 및 Lambda 쓰기 함수 등록

  • Lambda 함수를 생성하여 데이터 읽기

Bash
AWS CLI Bash 스크립트 사용
참고

GitHub에 더 많은 내용이 있습니다. 샘플 개발자 튜토리얼 리포지토리에서 전체 예제를 찾아보고 설정 및 실행 방법을 배워보세요.

#!/bin/bash # AWS Cloud Map Tutorial Script # This script demonstrates how to use AWS Cloud Map for service discovery with custom attributes set -euo pipefail # Set up logging LOG_FILE="cloudmap-tutorial.log" echo "AWS Cloud Map Tutorial Script" > "$LOG_FILE" echo "Started at $(date)" >> "$LOG_FILE" # Array to track created resources for cleanup CREATED_RESOURCES=() # Function to log commands and their output log_cmd() { echo "$ $1" | tee -a "$LOG_FILE" eval "$1" | tee -a "$LOG_FILE" } # Function to handle errors handle_error() { local LINE=$1 echo "An error occurred at line $LINE" | tee -a "$LOG_FILE" echo "Resources created so far:" | tee -a "$LOG_FILE" for resource in "${CREATED_RESOURCES[@]}"; do echo "- $resource" | tee -a "$LOG_FILE" done echo "Attempting to clean up resources..." | tee -a "$LOG_FILE" cleanup exit 1 } # Set up error handling trap 'handle_error $LINENO' ERR # Helper function to wait for Cloud Map operations to complete wait_for_operation() { local OPERATION_ID=$1 local TIMEOUT=300 # 5 minutes timeout local START_TIME START_TIME=$(date +%s) while true; do local STATUS STATUS=$(aws servicediscovery get-operation --operation-id "$OPERATION_ID" --query 'Operation.Status' --output text 2>/dev/null || echo "UNKNOWN") if [ "$STATUS" == "SUCCESS" ]; then echo "Operation completed successfully" | tee -a "$LOG_FILE" break elif [ "$STATUS" == "FAIL" ]; then echo "Operation failed" | tee -a "$LOG_FILE" return 1 fi local CURRENT_TIME CURRENT_TIME=$(date +%s) if [ $((CURRENT_TIME - START_TIME)) -gt $TIMEOUT ]; then echo "Operation timed out" | tee -a "$LOG_FILE" return 1 fi sleep 5 done return 0 } # Function to clean up resources cleanup() { echo "Cleaning up resources..." | tee -a "$LOG_FILE" # Reverse the order of created resources for proper deletion for ((i=${#CREATED_RESOURCES[@]}-1; i>=0; i--)); do resource="${CREATED_RESOURCES[$i]}" echo "Deleting $resource..." | tee -a "$LOG_FILE" if [[ $resource == "instance:"* ]]; then # Extract service ID and instance ID SERVICE_ID=$(echo "$resource" | cut -d':' -f2) INSTANCE_ID=$(echo "$resource" | cut -d':' -f3) # Check if instance exists before trying to deregister INSTANCE_EXISTS=$(aws servicediscovery list-instances --service-id "$SERVICE_ID" --query "Instances[?Id=='$INSTANCE_ID'].Id" --output text 2>/dev/null || echo "") if [[ -n "$INSTANCE_EXISTS" ]]; then OPERATION_ID=$(aws servicediscovery deregister-instance --service-id "$SERVICE_ID" --instance-id "$INSTANCE_ID" --query 'OperationId' --output text) # Wait for deregistration to complete echo "Waiting for instance deregistration to complete..." | tee -a "$LOG_FILE" wait_for_operation "$OPERATION_ID" || true else echo "Instance $INSTANCE_ID already deregistered" | tee -a "$LOG_FILE" fi elif [[ $resource == "lambda:"* ]]; then # Extract function name FUNCTION_NAME=$(echo "$resource" | cut -d':' -f2) aws lambda delete-function --function-name "$FUNCTION_NAME" 2>/dev/null || echo "Function already deleted" | tee -a "$LOG_FILE" elif [[ $resource == "role:"* ]]; then # Extract role name ROLE_NAME=$(echo "$resource" | cut -d':' -f2) # Detach all policies first for POLICY_ARN in $(aws iam list-attached-role-policies --role-name "$ROLE_NAME" --query 'AttachedPolicies[*].PolicyArn' --output text); do aws iam detach-role-policy --role-name "$ROLE_NAME" --policy-arn "$POLICY_ARN" done # Delete the role aws iam delete-role --role-name "$ROLE_NAME" 2>/dev/null || echo "Role already deleted" | tee -a "$LOG_FILE" elif [[ $resource == "dynamodb:"* ]]; then # Extract table name TABLE_NAME=$(echo "$resource" | cut -d':' -f2) aws dynamodb delete-table --table-name "$TABLE_NAME" 2>/dev/null || echo "Table already deleted" | tee -a "$LOG_FILE" # Wait for table deletion to complete echo "Waiting for DynamoDB table deletion to complete..." | tee -a "$LOG_FILE" aws dynamodb wait table-not-exists --table-name "$TABLE_NAME" 2>/dev/null || true fi done # Handle services separately to ensure all instances are deregistered first for ((i=${#CREATED_RESOURCES[@]}-1; i>=0; i--)); do resource="${CREATED_RESOURCES[$i]}" if [[ $resource == "service:"* ]]; then # Extract service ID SERVICE_ID=$(echo "$resource" | cut -d':' -f2) echo "Deleting service $SERVICE_ID..." | tee -a "$LOG_FILE" # Make sure all instances are deregistered INSTANCES=$(aws servicediscovery list-instances --service-id "$SERVICE_ID" --query 'Instances[*].Id' --output text 2>/dev/null || echo "") if [[ -n "$INSTANCES" ]]; then echo "Service still has instances. Waiting before deletion..." | tee -a "$LOG_FILE" sleep 10 fi # Try to delete the service aws servicediscovery delete-service --id "$SERVICE_ID" 2>/dev/null || echo "Service already deleted" | tee -a "$LOG_FILE" sleep 5 fi done # Handle namespaces last to ensure all services are deleted first for ((i=${#CREATED_RESOURCES[@]}-1; i>=0; i--)); do resource="${CREATED_RESOURCES[$i]}" if [[ $resource == "namespace:"* ]]; then # Extract namespace ID NAMESPACE_ID=$(echo "$resource" | cut -d':' -f2) echo "Deleting namespace $NAMESPACE_ID..." | tee -a "$LOG_FILE" # Check if namespace still has services SERVICES=$(aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NAMESPACE_ID,Condition=EQ" --query 'Services[*].Id' --output text 2>/dev/null || echo "") if [[ -n "$SERVICES" ]]; then echo "Namespace still has services. Deleting them first..." | tee -a "$LOG_FILE" for SERVICE_ID in $SERVICES; do echo "Deleting service $SERVICE_ID..." | tee -a "$LOG_FILE" aws servicediscovery delete-service --id "$SERVICE_ID" 2>/dev/null || true done sleep 5 fi # Try to delete the namespace OPERATION_ID=$(aws servicediscovery delete-namespace --id "$NAMESPACE_ID" --query 'OperationId' --output text 2>/dev/null || echo "") if [[ -n "$OPERATION_ID" ]]; then echo "Waiting for namespace deletion to complete..." | tee -a "$LOG_FILE" wait_for_operation "$OPERATION_ID" || true else echo "Failed to delete namespace or namespace already deleted" | tee -a "$LOG_FILE" fi fi done echo "Cleanup complete" | tee -a "$LOG_FILE" } # Step 1: Create an AWS Cloud Map namespace echo "Step 1: Creating AWS Cloud Map namespace..." | tee -a "$LOG_FILE" # Check if namespace already exists NAMESPACE_ID=$(aws servicediscovery list-namespaces --query "Namespaces[?Name=='cloudmap-tutorial'].Id" --output text 2>/dev/null || echo "") if [[ -z "$NAMESPACE_ID" || "$NAMESPACE_ID" == "None" ]]; then log_cmd "aws servicediscovery create-http-namespace --name cloudmap-tutorial --creator-request-id namespace-request-\$(date +%s)" OPERATION_ID=$(aws servicediscovery create-http-namespace --name cloudmap-tutorial --creator-request-id "namespace-request-$(date +%s)" --tags Key=project,Value=doc-smith Key=tutorial,Value=cloudmap-custom-attributes --query 'OperationId' --output text) # Wait for namespace creation to complete echo "Waiting for namespace creation to complete..." | tee -a "$LOG_FILE" wait_for_operation "$OPERATION_ID" # Get the namespace ID NAMESPACE_ID=$(aws servicediscovery list-namespaces --query "Namespaces[?Name=='cloudmap-tutorial'].Id" --output text) echo "Namespace created with ID: $NAMESPACE_ID" | tee -a "$LOG_FILE" else echo "Namespace cloudmap-tutorial already exists with ID: $NAMESPACE_ID" | tee -a "$LOG_FILE" fi CREATED_RESOURCES+=("namespace:$NAMESPACE_ID") # Step 2: Create a DynamoDB table echo "Step 2: Creating DynamoDB table..." | tee -a "$LOG_FILE" # Check if table already exists TABLE_EXISTS=$(aws dynamodb describe-table --table-name cloudmap 2>&1 || echo "NOT_EXISTS") if [[ $TABLE_EXISTS == *"ResourceNotFoundException"* || $TABLE_EXISTS == "NOT_EXISTS" ]]; then log_cmd "aws dynamodb create-table --table-name cloudmap --attribute-definitions AttributeName=id,AttributeType=S --key-schema AttributeName=id,KeyType=HASH --billing-mode PAY_PER_REQUEST --tags Key=project,Value=doc-smith Key=tutorial,Value=cloudmap-custom-attributes" # Wait for DynamoDB table to become active echo "Waiting for DynamoDB table to become active..." | tee -a "$LOG_FILE" aws dynamodb wait table-exists --table-name cloudmap else echo "DynamoDB table cloudmap already exists" | tee -a "$LOG_FILE" fi CREATED_RESOURCES+=("dynamodb:cloudmap") # Step 3: Create an AWS Cloud Map data service echo "Step 3: Creating AWS Cloud Map data service..." | tee -a "$LOG_FILE" # Get all services in the namespace echo "Listing all services in namespace $NAMESPACE_ID..." | tee -a "$LOG_FILE" SERVICES=$(aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NAMESPACE_ID,Condition=EQ" --query 'Services[*].[Id,Name]' --output text 2>/dev/null || echo "") echo "Services found: $SERVICES" | tee -a "$LOG_FILE" # Check if data service already exists DATA_SERVICE_ID="" while read -r id name || [[ -n "$id" ]]; do echo "Checking service: ID=$id, Name=$name" | tee -a "$LOG_FILE" if [[ "$name" == "data-service" ]]; then DATA_SERVICE_ID="$id" break fi done <<< "$SERVICES" if [[ -z "$DATA_SERVICE_ID" ]]; then echo "Data service does not exist, creating it..." | tee -a "$LOG_FILE" # Create the service and capture the ID directly echo "$ aws servicediscovery create-service --name data-service --namespace-id $NAMESPACE_ID --creator-request-id data-service-request-\$(date +%s)" | tee -a "$LOG_FILE" CREATE_OUTPUT=$(aws servicediscovery create-service --name data-service --namespace-id "$NAMESPACE_ID" --tags Key=project,Value=doc-smith Key=tutorial,Value=cloudmap-custom-attributes --creator-request-id "data-service-request-$(date +%s)") echo "$CREATE_OUTPUT" | tee -a "$LOG_FILE" # Extract the service ID using AWS CLI query DATA_SERVICE_ID=$(aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NAMESPACE_ID,Condition=EQ" --query "Services[?Name=='data-service'].Id" --output text) echo "Data service created with ID: $DATA_SERVICE_ID" | tee -a "$LOG_FILE" else echo "Data service already exists with ID: $DATA_SERVICE_ID" | tee -a "$LOG_FILE" fi CREATED_RESOURCES+=("service:$DATA_SERVICE_ID") # Register DynamoDB table as a service instance echo "Registering DynamoDB table as a service instance..." | tee -a "$LOG_FILE" # Check if instance already exists INSTANCE_EXISTS=$(aws servicediscovery list-instances --service-id "$DATA_SERVICE_ID" --query "Instances[?Id=='data-instance'].Id" --output text 2>/dev/null || echo "") if [[ -z "$INSTANCE_EXISTS" ]]; then AWS_REGION=$(aws configure get region || echo "us-east-1") log_cmd "aws servicediscovery register-instance --service-id $DATA_SERVICE_ID --instance-id data-instance --attributes tablename=cloudmap,region=$AWS_REGION" OPERATION_ID=$(aws servicediscovery register-instance --service-id "$DATA_SERVICE_ID" --instance-id data-instance --attributes "tablename=cloudmap,region=$AWS_REGION" --query 'OperationId' --output text) # Wait for instance registration to complete echo "Waiting for instance registration to complete..." | tee -a "$LOG_FILE" wait_for_operation "$OPERATION_ID" else echo "Instance data-instance already exists" | tee -a "$LOG_FILE" fi CREATED_RESOURCES+=("instance:$DATA_SERVICE_ID:data-instance") # Step 4: Create an IAM role for Lambda echo "Step 4: Creating IAM role for Lambda..." | tee -a "$LOG_FILE" # Create a trust policy for Lambda cat > lambda-trust-policy.json << 'EOF' { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF # Check if role already exists echo "Checking if IAM role already exists..." | tee -a "$LOG_FILE" ROLE_EXISTS=$(aws iam get-role --role-name cloudmap-tutorial-role 2>&1 || echo "NOT_EXISTS") if [[ $ROLE_EXISTS == *"NoSuchEntity"* || $ROLE_EXISTS == "NOT_EXISTS" ]]; then log_cmd "aws iam create-role --role-name cloudmap-tutorial-role --assume-role-policy-document file://lambda-trust-policy.json" aws iam tag-role --role-name cloudmap-tutorial-role --tags Key=project,Value=doc-smith Key=tutorial,Value=cloudmap-custom-attributes else echo "Role cloudmap-tutorial-role already exists, using existing role" | tee -a "$LOG_FILE" fi # Create a custom policy with least privilege cat > cloudmap-policy.json << 'EOF' { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "dynamodb:PutItem", "dynamodb:GetItem", "dynamodb:Scan" ], "Resource": "arn:aws:dynamodb:*:*:table/cloudmap" }, { "Effect": "Allow", "Action": [ "servicediscovery:DiscoverInstances" ], "Resource": "*" } ] } EOF # Check if policy already exists POLICY_ARN=$(aws iam list-policies --query "Policies[?PolicyName=='CloudMapTutorialPolicy'].Arn" --output text 2>/dev/null || echo "") if [[ -z "$POLICY_ARN" ]]; then echo "Creating CloudMapTutorialPolicy..." | tee -a "$LOG_FILE" echo "$ aws iam create-policy --policy-name CloudMapTutorialPolicy --policy-document file://cloudmap-policy.json" | tee -a "$LOG_FILE" CREATE_OUTPUT=$(aws iam create-policy --policy-name CloudMapTutorialPolicy --policy-document file://cloudmap-policy.json) echo "$CREATE_OUTPUT" | tee -a "$LOG_FILE" POLICY_ARN=$(aws iam list-policies --query "Policies[?PolicyName=='CloudMapTutorialPolicy'].Arn" --output text) else echo "Policy CloudMapTutorialPolicy already exists with ARN: $POLICY_ARN" | tee -a "$LOG_FILE" fi echo "$ aws iam attach-role-policy --role-name cloudmap-tutorial-role --policy-arn $POLICY_ARN" | tee -a "$LOG_FILE" aws iam attach-role-policy --role-name cloudmap-tutorial-role --policy-arn "$POLICY_ARN" | tee -a "$LOG_FILE" echo "$ aws iam attach-role-policy --role-name cloudmap-tutorial-role --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" | tee -a "$LOG_FILE" aws iam attach-role-policy --role-name cloudmap-tutorial-role --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole | tee -a "$LOG_FILE" # Wait for role to propagate echo "Waiting for IAM role to propagate..." | tee -a "$LOG_FILE" sleep 10 ROLE_ARN=$(aws iam get-role --role-name cloudmap-tutorial-role --query 'Role.Arn' --output text) CREATED_RESOURCES+=("role:cloudmap-tutorial-role") # Step 5: Create an AWS Cloud Map app service echo "Step 5: Creating AWS Cloud Map app service..." | tee -a "$LOG_FILE" # Get all services in the namespace SERVICES=$(aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NAMESPACE_ID,Condition=EQ" --query 'Services[*].[Id,Name]' --output text 2>/dev/null || echo "") # Check if app service already exists APP_SERVICE_ID="" while read -r id name || [[ -n "$id" ]]; do if [[ "$name" == "app-service" ]]; then APP_SERVICE_ID="$id" break fi done <<< "$SERVICES" if [[ -z "$APP_SERVICE_ID" ]]; then echo "App service does not exist, creating it..." | tee -a "$LOG_FILE" # Create the service and capture the ID directly echo "$ aws servicediscovery create-service --name app-service --namespace-id $NAMESPACE_ID --creator-request-id app-service-request-\$(date +%s)" | tee -a "$LOG_FILE" CREATE_OUTPUT=$(aws servicediscovery create-service --name app-service --namespace-id "$NAMESPACE_ID" --tags Key=project,Value=doc-smith Key=tutorial,Value=cloudmap-custom-attributes --creator-request-id "app-service-request-$(date +%s)") echo "$CREATE_OUTPUT" | tee -a "$LOG_FILE" # Extract the service ID using AWS CLI query APP_SERVICE_ID=$(aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NAMESPACE_ID,Condition=EQ" --query "Services[?Name=='app-service'].Id" --output text) echo "App service created with ID: $APP_SERVICE_ID" | tee -a "$LOG_FILE" else echo "App service already exists with ID: $APP_SERVICE_ID" | tee -a "$LOG_FILE" fi CREATED_RESOURCES+=("service:$APP_SERVICE_ID") # Step 6: Create a Lambda function to write data echo "Step 6: Creating Lambda function to write data..." | tee -a "$LOG_FILE" # Create Lambda function code cat > writefunction.py << 'EOF' import boto3 import json import random import os def lambda_handler(event, context): # Use AWS Cloud Map to discover the DynamoDB table serviceclient = boto3.client('servicediscovery') try: # Discover the data service instance response = serviceclient.discover_instances( NamespaceName='cloudmap-tutorial', ServiceName='data-service' ) if not response.get('Instances'): return { 'statusCode': 404, 'body': json.dumps('No service instances found') } # Extract table name and region from the instance attributes attributes = response['Instances'][0].get('Attributes', {}) tablename = attributes.get('tablename', 'cloudmap') region = attributes.get('region', os.environ.get('AWS_REGION', 'us-east-1')) # Create DynamoDB client in the specified region dynamodb = boto3.resource('dynamodb', region_name=region) table = dynamodb.Table(tablename) # Write data to the table table.put_item( Item={ 'id': str(random.randint(1, 100)), 'todo': str(event) } ) return { 'statusCode': 200, 'body': json.dumps('Data written successfully!') } except Exception as e: return { 'statusCode': 500, 'body': json.dumps(f'Error: {str(e)}') } EOF # Zip the function code log_cmd "zip writefunction.zip writefunction.py" # Create the Lambda function FUNCTION_EXISTS=$(aws lambda list-functions --query "Functions[?FunctionName=='writefunction'].FunctionName" --output text 2>/dev/null || echo "") if [[ -z "$FUNCTION_EXISTS" ]]; then log_cmd "aws lambda create-function --function-name writefunction --runtime python3.12 --role $ROLE_ARN --handler writefunction.lambda_handler --zip-file fileb://writefunction.zip --architectures x86_64 --timeout 10 --tags project=doc-smith,tutorial=cloudmap-custom-attributes" # Wait for the Lambda function to be active before updating echo "Waiting for Lambda function to become active..." | tee -a "$LOG_FILE" function_state="Pending" while [ "$function_state" == "Pending" ]; do sleep 5 function_state=$(aws lambda get-function --function-name writefunction --query 'Configuration.State' --output text) echo "Current function state: $function_state" | tee -a "$LOG_FILE" done else echo "Lambda function writefunction already exists" | tee -a "$LOG_FILE" fi CREATED_RESOURCES+=("lambda:writefunction") # Step 7: Register the Lambda write function as an AWS Cloud Map service instance echo "Step 7: Registering Lambda write function as a service instance..." | tee -a "$LOG_FILE" # Check if instance already exists INSTANCE_EXISTS=$(aws servicediscovery list-instances --service-id "$APP_SERVICE_ID" --query "Instances[?Id=='write-instance'].Id" --output text 2>/dev/null || echo "") if [[ -z "$INSTANCE_EXISTS" ]]; then log_cmd "aws servicediscovery register-instance --service-id $APP_SERVICE_ID --instance-id write-instance --attributes action=write,functionname=writefunction" OPERATION_ID=$(aws servicediscovery register-instance --service-id "$APP_SERVICE_ID" --instance-id write-instance --attributes action=write,functionname=writefunction --query 'OperationId' --output text) # Wait for instance registration to complete echo "Waiting for write instance registration to complete..." | tee -a "$LOG_FILE" wait_for_operation "$OPERATION_ID" else echo "Instance write-instance already exists" | tee -a "$LOG_FILE" fi CREATED_RESOURCES+=("instance:$APP_SERVICE_ID:write-instance") # Step 8: Create a Lambda function to read data echo "Step 8: Creating Lambda function to read data..." | tee -a "$LOG_FILE" # Create Lambda function code cat > readfunction.py << 'EOF' import boto3 import json import os def lambda_handler(event, context): # Use AWS Cloud Map to discover the DynamoDB table serviceclient = boto3.client('servicediscovery') try: # Discover the data service instance response = serviceclient.discover_instances( NamespaceName='cloudmap-tutorial', ServiceName='data-service' ) if not response.get('Instances'): return { 'statusCode': 404, 'body': json.dumps('No service instances found') } # Extract table name and region from the instance attributes attributes = response['Instances'][0].get('Attributes', {}) tablename = attributes.get('tablename', 'cloudmap') region = attributes.get('region', os.environ.get('AWS_REGION', 'us-east-1')) # Create DynamoDB client in the specified region dynamodb = boto3.resource('dynamodb', region_name=region) table = dynamodb.Table(tablename) # Read data from the table response = table.scan() return { 'statusCode': 200, 'body': json.dumps(response.get('Items', [])) } except Exception as e: return { 'statusCode': 500, 'body': json.dumps(f'Error: {str(e)}') } EOF # Zip the function code log_cmd "zip readfunction.zip readfunction.py" # Create the Lambda function FUNCTION_EXISTS=$(aws lambda list-functions --query "Functions[?FunctionName=='readfunction'].FunctionName" --output text 2>/dev/null || echo "") if [[ -z "$FUNCTION_EXISTS" ]]; then log_cmd "aws lambda create-function --function-name readfunction --runtime python3.12 --role $ROLE_ARN --handler readfunction.lambda_handler --zip-file fileb://readfunction.zip --architectures x86_64 --timeout 10 --tags project=doc-smith,tutorial=cloudmap-custom-attributes" # Wait for the Lambda function to be active before updating echo "Waiting for Lambda function to become active..." | tee -a "$LOG_FILE" function_state="Pending" while [ "$function_state" == "Pending" ]; do sleep 5 function_state=$(aws lambda get-function --function-name readfunction --query 'Configuration.State' --output text) echo "Current function state: $function_state" | tee -a "$LOG_FILE" done else echo "Lambda function readfunction already exists" | tee -a "$LOG_FILE" fi CREATED_RESOURCES+=("lambda:readfunction") # Step 9: Register the Lambda read function as an AWS Cloud Map service instance echo "Step 9: Registering Lambda read function as a service instance..." | tee -a "$LOG_FILE" # Check if instance already exists INSTANCE_EXISTS=$(aws servicediscovery list-instances --service-id "$APP_SERVICE_ID" --query "Instances[?Id=='read-instance'].Id" --output text 2>/dev/null || echo "") if [[ -z "$INSTANCE_EXISTS" ]]; then log_cmd "aws servicediscovery register-instance --service-id $APP_SERVICE_ID --instance-id read-instance --attributes action=read,functionname=readfunction" OPERATION_ID=$(aws servicediscovery register-instance --service-id "$APP_SERVICE_ID" --instance-id read-instance --attributes action=read,functionname=readfunction --query 'OperationId' --output text) # Wait for read instance registration to complete echo "Waiting for read instance registration to complete..." | tee -a "$LOG_FILE" wait_for_operation "$OPERATION_ID" else echo "Instance read-instance already exists" | tee -a "$LOG_FILE" fi CREATED_RESOURCES+=("instance:$APP_SERVICE_ID:read-instance") # Step 10: Create Python clients to interact with the services echo "Step 10: Creating Python clients..." | tee -a "$LOG_FILE" cat > writeclient.py << 'EOF' #!/usr/bin/env python3 import boto3 import json import sys try: serviceclient = boto3.client('servicediscovery') response = serviceclient.discover_instances( NamespaceName='cloudmap-tutorial', ServiceName='app-service', QueryParameters={'action': 'write'} ) if not response.get('Instances'): print("No write service instances found", file=sys.stderr) sys.exit(1) functionname = response["Instances"][0]["Attributes"]["functionname"] lambdaclient = boto3.client('lambda') resp = lambdaclient.invoke( FunctionName=functionname, Payload=json.dumps('This is a test data'), InvocationType='RequestResponse' ) print(resp["Payload"].read().decode()) except Exception as e: print(f"Error: {str(e)}", file=sys.stderr) sys.exit(1) EOF cat > readclient.py << 'EOF' #!/usr/bin/env python3 import boto3 import json import sys try: serviceclient = boto3.client('servicediscovery') response = serviceclient.discover_instances( NamespaceName='cloudmap-tutorial', ServiceName='app-service', QueryParameters={'action': 'read'} ) if not response.get('Instances'): print("No read service instances found", file=sys.stderr) sys.exit(1) functionname = response["Instances"][0]["Attributes"]["functionname"] lambdaclient = boto3.client('lambda') resp = lambdaclient.invoke( FunctionName=functionname, InvocationType='RequestResponse' ) print(resp["Payload"].read().decode()) except Exception as e: print(f"Error: {str(e)}", file=sys.stderr) sys.exit(1) EOF chmod +x writeclient.py readclient.py echo "Running write client..." | tee -a "$LOG_FILE" log_cmd "python3 writeclient.py" || echo "Write client execution completed with warnings" | tee -a "$LOG_FILE" echo "Running read client..." | tee -a "$LOG_FILE" log_cmd "python3 readclient.py" || echo "Read client execution completed with warnings" | tee -a "$LOG_FILE" # Step 11: Clean up resources echo "Resources created:" | tee -a "$LOG_FILE" for resource in "${CREATED_RESOURCES[@]}"; do echo "- $resource" | tee -a "$LOG_FILE" done echo "" | tee -a "$LOG_FILE" echo "==========================================" | tee -a "$LOG_FILE" echo "CLEANUP CONFIRMATION" | tee -a "$LOG_FILE" echo "==========================================" | tee -a "$LOG_FILE" echo "Cleaning up all created resources..." | tee -a "$LOG_FILE" cleanup echo "Script completed at $(date)" | tee -a "$LOG_FILE"