

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

# 를 사용하여 사용자 지정 속성과 함께 AWS Cloud Map 서비스 검색을 사용하는 방법을 알아봅니다. AWS CLI
<a name="tutorial-microservices-cli"></a>

이 자습서에서는 사용자 지정 속성과 함께 AWS Cloud Map 서비스 검색을 사용하는 방법을 보여줍니다. 를 사용하여 사용자 지정 속성을 사용하여 리소스를 동적으로 AWS Cloud Map 검색하는 마이크로서비스 애플리케이션을 생성합니다. 애플리케이션은 모든 리소스가 등록된 상태에서 DynamoDB 테이블에 데이터를 쓰고 읽는 두 Lambda 함수로 구성됩니다 AWS Cloud Map.

자습서 AWS Management Console 버전은 섹션을 참조하세요[사용자 지정 속성과 함께 AWS Cloud Map 서비스 검색을 사용하는 방법을 알아봅니다.](tutorial-microservices.md).

## 사전 조건
<a name="prerequisites"></a>

이 자습서를 시작하기 전에의 단계를 완료합니다[를 사용하도록 설정 AWS Cloud Map](setting-up-cloud-map.md).

## AWS Cloud Map 네임스페이스 생성
<a name="create-an-aws-cloud-map-namespace"></a>

네임스페이스는 애플리케이션의 서비스를 그룹화하는 데 사용되는 구문입니다. 이 단계에서는 AWS Cloud Map API 호출을 통해 리소스를 검색할 수 있는 네임스페이스를 생성합니다.

1. 다음 명령을 실행하여 HTTP 네임스페이스를 생성합니다.

   ```
   aws servicediscovery create-http-namespace \
     --name cloudmap-tutorial \
     --creator-request-id cloudmap-tutorial-request
   ```

   명령은 작업 ID를 반환합니다. 다음 명령을 사용하여 작업 상태를 확인할 수 있습니다.

   ```
   aws servicediscovery get-operation \
     --operation-id operation-id
   ```

1. 네임스페이스가 생성되면 후속 명령에 사용할 네임스페이스의 ID를 검색할 수 있습니다.

   ```
   aws servicediscovery list-namespaces \
     --query "Namespaces[?Name=='cloudmap-tutorial'].Id" \
     --output text
   ```

1. 나중에 사용할 수 있도록 네임스페이스 ID를 변수에 저장합니다.

   ```
   NAMESPACE_ID=$(aws servicediscovery list-namespaces \
     --query "Namespaces[?Name=='cloudmap-tutorial'].Id" \
     --output text)
   ```

## DynamoDB 테이블 생성
<a name="create-a-dynamodb-table"></a>

그런 다음 애플리케이션에 대한 데이터를 저장할 DynamoDB 테이블을 생성합니다.

1. 다음 명령을 실행하여 테이블을 생성합니다.

   ```
   aws dynamodb create-table \
     --table-name cloudmap \
     --attribute-definitions AttributeName=id,AttributeType=S \
     --key-schema AttributeName=id,KeyType=HASH \
     --billing-mode PAY_PER_REQUEST
   ```

1. 계속하기 전에 테이블이 활성화될 때까지 기다립니다.

   ```
   aws dynamodb wait table-exists --table-name cloudmap
   ```

   이 명령은 테이블이 완전히 생성되고 사용할 준비가 될 때까지 기다립니다.

## AWS Cloud Map 데이터 서비스 생성 및 DynamoDB 테이블 등록
<a name="create-an-aws-cloud-map-data-service-and-register-the-dynamodb-table"></a>

이제 네임스페이스에서 데이터 스토리지 리소스를 나타내는 서비스를 생성합니다.

1. 다음 명령을 실행하여 데이터 스토리지 리소스에 대한 AWS Cloud Map 서비스를 생성합니다.

   ```
   aws servicediscovery create-service \
     --name data-service \
     --namespace-id $NAMESPACE_ID \
     --creator-request-id data-service-request
   ```

1. 데이터 서비스의 서비스 ID를 가져옵니다.

   ```
   DATA_SERVICE_ID=$(aws servicediscovery list-services \
     --query "Services[?Name=='data-service'].Id" \
     --output text)
   ```

1. 테이블 이름을 지정하는 사용자 지정 속성을 사용하여 DynamoDB 테이블을 서비스 인스턴스로 등록합니다.

   ```
   aws servicediscovery register-instance \
     --service-id $DATA_SERVICE_ID \
     --instance-id data-instance \
     --attributes tablename=cloudmap
   ```

   사용자 지정 속성을 `tablename=cloudmap` 사용하면 다른 서비스에서 DynamoDB 테이블 이름을 동적으로 검색할 수 있습니다.

## Lambda 함수에 대한 IAM 역할 생성
<a name="create-an-iam-role-for-lambda-functions"></a>

Lambda 함수가 리소스에 액세스하는 AWS 데 사용할 IAM 역할을 생성합니다.

1. 다음 JSON을 사용하여 IAM 역할에 대한 신뢰 정책 문서를 생성합니다.

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "lambda.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

------

1. 다음 명령을 실행하여 신뢰 정책을 사용하여 IAM 역할을 생성합니다.

   ```
   aws iam create-role \
     --role-name cloudmap-tutorial-role \
     --assume-role-policy-document file://lambda-trust-policy.json
   ```

1. 다음 JSON을 사용하여 최소 권한 권한이 있는 사용자 지정 IAM 정책에 대한 파일을 생성합니다.

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "logs:CreateLogGroup",
           "logs:CreateLogStream",
           "logs:PutLogEvents"
         ],
         "Resource": "arn:aws:logs:*:*:*"
       },
       {
         "Effect": "Allow",
         "Action": [
           "servicediscovery:DiscoverInstances"
         ],
         "Resource": "*"
       },
       {
         "Effect": "Allow",
         "Action": [
           "dynamodb:PutItem",
           "dynamodb:Scan"
         ],
         "Resource": "arn:aws:dynamodb:*:*:table/cloudmap"
       }
     ]
   }
   ```

------

1. 정책을 생성하고 IAM 역할에 연결합니다.

   ```
   aws iam create-policy \
     --policy-name CloudMapTutorialPolicy \
     --policy-document file://cloudmap-policy.json
   
   POLICY_ARN=$(aws iam list-policies \
     --query "Policies[?PolicyName=='CloudMapTutorialPolicy'].Arn" \
     --output text)
   
   aws iam attach-role-policy \
     --role-name cloudmap-tutorial-role \
     --policy-arn $POLICY_ARN
   
   aws iam attach-role-policy \
     --role-name cloudmap-tutorial-role \
     --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
   ```

## Lambda 함수를 생성하여 데이터 쓰기
<a name="create-the-lambda-function-to-write-data"></a>

DynamoDB 테이블에 데이터를 쓰는 Lambda 함수를 생성하려면 다음 단계를 따르세요.

1. 쓰기 함수에 대한 Python 파일을 생성합니다.

   ```
   cat > writefunction.py << EOF
   import json
   import boto3
   import random
   
   def lambda_handler(event, context):
       try:
           serviceclient = boto3.client('servicediscovery')
           
           response = serviceclient.discover_instances(
               NamespaceName='cloudmap-tutorial',
               ServiceName='data-service')
           
           if not response.get("Instances"):
               return {
                   'statusCode': 500,
                   'body': json.dumps({"error": "No instances found"})
               }
               
           tablename = response["Instances"][0]["Attributes"].get("tablename")
           if not tablename:
               return {
                   'statusCode': 500,
                   'body': json.dumps({"error": "Table name attribute not found"})
               }
              
           dynamodbclient = boto3.resource('dynamodb')
              
           table = dynamodbclient.Table(tablename)
           
           # Validate input
           if not isinstance(event, str):
               return {
                   'statusCode': 400,
                   'body': json.dumps({"error": "Input must be a string"})
               }
              
           response = table.put_item(
               Item={ 'id': str(random.randint(1,100)), 'todo': event })
              
           return {
               'statusCode': 200,
               'body': json.dumps(response)
           }
       except Exception as e:
           return {
               'statusCode': 500,
               'body': json.dumps({"error": str(e)})
           }
   EOF
   ```

   이 함수는 AWS Cloud Map 를 사용하여 사용자 지정 속성에서 DynamoDB 테이블 이름을 검색한 다음 테이블에 데이터를 씁니다.

1. Lambda 함수를 패키징하고 배포합니다.

   ```
   zip writefunction.zip writefunction.py
   
   ROLE_ARN=$(aws iam get-role --role-name cloudmap-tutorial-role \
     --query 'Role.Arn' --output text)
   
   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
   ```

1. 제한 시간 오류를 방지하려면 함수 제한 시간을 업데이트합니다.

   ```
   aws lambda update-function-configuration \
     --function-name writefunction \
     --timeout 5
   ```

## AWS Cloud Map 앱 서비스 생성 및 Lambda 쓰기 함수 등록
<a name="create-an-aws-cloud-map-app-service-and-register-the-lambda-write-function"></a>

네임스페이스에 애플리케이션 함수를 나타내는 다른 서비스를 생성하려면 다음 단계를 따르세요.

1. 애플리케이션 함수에 대한 서비스를 생성합니다.

   ```
   aws servicediscovery create-service \
     --name app-service \
     --namespace-id $NAMESPACE_ID \
     --creator-request-id app-service-request
   ```

1. 앱 서비스의 서비스 ID를 가져옵니다.

   ```
   APP_SERVICE_ID=$(aws servicediscovery list-services \
     --query "Services[?Name=='app-service'].Id" \
     --output text)
   ```

1. Lambda 쓰기 함수를 사용자 지정 속성이 있는 서비스 인스턴스로 등록합니다.

   ```
   aws servicediscovery register-instance \
     --service-id $APP_SERVICE_ID \
     --instance-id write-instance \
     --attributes action=write,functionname=writefunction
   ```

   사용자 지정 속성 `action=write` 및는 클라이언트가 목적에 따라이 함수를 검색할 수 `functionname=writefunction` 있도록 허용합니다.

## Lambda 함수를 생성하여 데이터 읽기
<a name="create-the-lambda-function-to-read-data"></a>

DynamoDB 테이블에서 데이터를 읽는 Lambda 함수를 생성하려면 다음 단계를 따릅니다.

1. 읽기 함수에 대한 Python 파일을 생성합니다.

   ```
   cat > readfunction.py << EOF
   import json
   import boto3
   
   def lambda_handler(event, context):
       try:
           serviceclient = boto3.client('servicediscovery')
   
           response = serviceclient.discover_instances(
               NamespaceName='cloudmap-tutorial', 
               ServiceName='data-service')
           
           if not response.get("Instances"):
               return {
                   'statusCode': 500,
                   'body': json.dumps({"error": "No instances found"})
               }
               
           tablename = response["Instances"][0]["Attributes"].get("tablename")
           if not tablename:
               return {
                   'statusCode': 500,
                   'body': json.dumps({"error": "Table name attribute not found"})
               }
              
           dynamodbclient = boto3.resource('dynamodb')
              
           table = dynamodbclient.Table(tablename)
           
           # Use pagination for larger tables
           response = table.scan(
               Select='ALL_ATTRIBUTES',
               Limit=50  # Limit results for demonstration purposes
           )
           
           # For production, you would implement pagination like this:
           # items = []
           # while 'LastEvaluatedKey' in response:
           #     items.extend(response['Items'])
           #     response = table.scan(
           #         Select='ALL_ATTRIBUTES',
           #         ExclusiveStartKey=response['LastEvaluatedKey']
           #     )
           # items.extend(response['Items'])
   
           return {
               'statusCode': 200,
               'body': json.dumps(response)
           }
       except Exception as e:
           return {
               'statusCode': 500,
               'body': json.dumps({"error": str(e)})
           }
   EOF
   ```

   또한이 함수는 AWS Cloud Map 를 사용하여 DynamoDB 테이블 이름을 검색한 다음 테이블에서 데이터를 읽습니다. 여기에는 오류 처리 및 페이지 매김 주석이 포함됩니다.

1. Lambda 함수를 패키징하고 배포합니다.

   ```
   zip readfunction.zip readfunction.py
   
   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
   ```

1. 함수 제한 시간을 업데이트합니다.

   ```
   aws lambda update-function-configuration \
     --function-name readfunction \
     --timeout 5
   ```

## Lambda 읽기 함수를 서비스 인스턴스로 등록
<a name="register-the-lambda-read-function-as-a-service-instance"></a>

Lambda 읽기 함수를 앱 서비스의 다른 서비스 인스턴스로 등록하려면 다음 단계를 따릅니다.

```
aws servicediscovery register-instance \
  --service-id $APP_SERVICE_ID \
  --instance-id read-instance \
  --attributes action=read,functionname=readfunction
```

사용자 지정 속성 `action=read` 및를 `functionname=readfunction` 사용하면 클라이언트가 목적에 따라이 함수를 검색할 수 있습니다.

## 클라이언트 애플리케이션 생성 및 실행
<a name="create-and-run-client-applications"></a>

가 쓰기 함수를 검색하고 호출하는 AWS Cloud Map 데 사용하는 Python 클라이언트 애플리케이션을 생성하려면 다음 단계를 따르세요.

1. 쓰기 클라이언트 애플리케이션을 위한 Python 파일을 생성합니다.

   ```
   cat > writeclient.py << EOF
   import boto3
   import json
   
   try:
       serviceclient = boto3.client('servicediscovery')
   
       print("Discovering write function...")
       response = serviceclient.discover_instances(
           NamespaceName='cloudmap-tutorial', 
           ServiceName='app-service', 
           QueryParameters={ 'action': 'write' }
       )
   
       if not response.get("Instances"):
           print("Error: No instances found")
           exit(1)
           
       functionname = response["Instances"][0]["Attributes"].get("functionname")
       if not functionname:
           print("Error: Function name attribute not found")
           exit(1)
           
       print(f"Found function: {functionname}")
   
       lambdaclient = boto3.client('lambda')
   
       print("Invoking Lambda function...")
       resp = lambdaclient.invoke(
           FunctionName=functionname, 
           Payload='"This is a test data"'
       )
   
       payload = resp["Payload"].read()
       print(f"Response: {payload.decode('utf-8')}")
       
   except Exception as e:
       print(f"Error: {str(e)}")
   EOF
   ```

   이 클라이언트는 `QueryParameters` 옵션을 사용하여 `action=write` 속성이 있는 서비스 인스턴스를 찾습니다.

1. 읽기 클라이언트 애플리케이션을 위한 Python 파일을 생성합니다.

   ```
   cat > readclient.py << EOF
   import boto3
   import json
   
   try:
       serviceclient = boto3.client('servicediscovery')
   
       print("Discovering read function...")
       response = serviceclient.discover_instances(
           NamespaceName='cloudmap-tutorial', 
           ServiceName='app-service', 
           QueryParameters={ 'action': 'read' }
       )
   
       if not response.get("Instances"):
           print("Error: No instances found")
           exit(1)
           
       functionname = response["Instances"][0]["Attributes"].get("functionname")
       if not functionname:
           print("Error: Function name attribute not found")
           exit(1)
           
       print(f"Found function: {functionname}")
   
       lambdaclient = boto3.client('lambda')
   
       print("Invoking Lambda function...")
       resp = lambdaclient.invoke(
           FunctionName=functionname, 
           InvocationType='RequestResponse'
       )
   
       payload = resp["Payload"].read()
       print(f"Response: {payload.decode('utf-8')}")
       
   except Exception as e:
       print(f"Error: {str(e)}")
   EOF
   ```

1. 쓰기 클라이언트를 실행하여 DynamoDB 테이블에 데이터를 추가합니다.

   ```
   python3 writeclient.py
   ```

   출력에는 HTTP 상태 코드 200으로 성공적인 응답이 표시되어야 합니다.

1. 읽기 클라이언트를 실행하여 DynamoDB 테이블에서 데이터를 검색합니다.

   ```
   python3 readclient.py
   ```

   출력에는 무작위로 생성된 ID와 "테스트 데이터입니다" 값을 포함하여 테이블에 기록된 데이터가 표시되어야 합니다.

## 리소스 정리
<a name="clean-up-resources"></a>

자습서를 마치면 추가 요금이 발생하지 않도록 리소스를 정리합니다.

1. 먼저 다음 명령을 실행하여 서비스 인스턴스의 등록을 취소합니다.

   ```
   aws servicediscovery deregister-instance \
     --service-id $APP_SERVICE_ID \
     --instance-id read-instance
   
   aws servicediscovery deregister-instance \
     --service-id $APP_SERVICE_ID \
     --instance-id write-instance
   
   aws servicediscovery deregister-instance \
     --service-id $DATA_SERVICE_ID \
     --instance-id data-instance
   ```

1. 다음 명령을 실행하여 서비스를 삭제합니다.

   ```
   aws servicediscovery delete-service \
     --id $APP_SERVICE_ID
   
   aws servicediscovery delete-service \
     --id $DATA_SERVICE_ID
   ```

1. 다음 명령을 실행하여 네임스페이스를 삭제합니다.

   ```
   aws servicediscovery delete-namespace \
     --id $NAMESPACE_ID
   ```

1. 다음 명령을 실행하여 Lambda 함수를 삭제합니다.

   ```
   aws lambda delete-function --function-name writefunction
   aws lambda delete-function --function-name readfunction
   ```

1. 다음 명령을 실행하여 IAM 역할 및 정책을 삭제합니다.

   ```
   aws iam detach-role-policy \
     --role-name cloudmap-tutorial-role \
     --policy-arn $POLICY_ARN
   
   aws iam detach-role-policy \
     --role-name cloudmap-tutorial-role \
     --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
   
   aws iam delete-policy \
     --policy-arn $POLICY_ARN
   
   aws iam delete-role --role-name cloudmap-tutorial-role
   ```

1. 다음 명령을 실행하여 DynamoDB 테이블을 삭제합니다.

   ```
   aws dynamodb delete-table --table-name cloudmap
   ```

1. 다음 명령을 실행하여 임시 파일을 정리합니다.

   ```
   rm -f lambda-trust-policy.json cloudmap-policy.json writefunction.py readfunction.py writefunction.zip readfunction.zip writeclient.py readclient.py
   ```