Tutorial: Using Amazon Cloud Map service discovery with custom attributes - Amazon Cloud Map
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).

Tutorial: Using Amazon Cloud Map service discovery with custom attributes

This tutorial demonstrates how you can use Amazon Cloud Map service discovery with custom attributes that are discoverable using the Amazon Cloud Map API. This tutorial walks you through creating a client application in an Amazon Cloud9 environment that uses two Lambda functions to write data to a DynamoDB table and then read from the table. The Lambda functions and DynamoDB table are registered in Amazon Cloud Map as service instances. The code in the client application and Lambda functions uses Amazon Cloud Map custom attributes to discover the resources needed to perform the job.

The following diagram demonstrates the high level architecture this tutorial uses.


   The diagram showing the architecture design for this tutorial.
Important

You will create Amazon resources during the workshop which will incur a cost in your Amazon account. It is recommended to clean-up the resources as soon as you finish the workshop to minimize the cost.

Prerequisites

The following prerequisites must be met to complete this tutorial successfully.

If you do not have an Amazon Web Services account, use the following procedure to create one.

To sign up for Amazon Web Services
  1. Open http://www.amazonaws.cn/ and choose Sign Up.

  2. Follow the on-screen instructions.

Amazon sends you a confirmation email after the sign-up process is complete. At any time, you can view your current account activity and manage your account by going to http://www.amazonaws.cn/ and choosing My Account.

After you sign up for an Amazon Web Services account, safeguard your administrative user by turning on multi-factor authentication (MFA). For instructions, see Enable a virtual MFA device for an IAM user (console) in the IAM User Guide.

To give other users access to your Amazon Web Services account resources, create IAM users. To secure your IAM users, turn on MFA and only give the IAM users the permissions needed to perform their tasks.

For more information about creating and securing IAM users, see the following topics in the IAM User Guide:

Step 1: Create an Amazon Cloud Map namespace

In this step, you create an Amazon Cloud Map namespace. A namespace is a construct used to group services for an application. When you create the namespace, you specify how the resources will be discoverable. For this tutorial, the resources created in this namespace will be discoverable with Amazon Cloud Map API calls using custom attributes. You will learn about this more in a later step.

  1. Sign in to the Amazon Web Services Management Console and open the Amazon Cloud Map console at https://console.amazonaws.cn/cloudmap/.

  2. Choose Create namespace.

  3. For Namespace name, specify cloudmap-tutorial.

  4. (Optional) For Namespace description, specify a description for what you intend to use the namespace for.

  5. For Instance discovery, select API calls.

  6. Leave the rest of the default values and choose Create namespace.

Step 2: Create a DynamoDB table

In this step, you create a DynamoDB table which is used to store and retrieve data for the sample application created later in this tutorial.

  1. Sign in to the Amazon Web Services Management Console and open the DynamoDB console at https://console.amazonaws.cn/dynamodb/.

  2. In the left navigation pane, choose Tables, Create table.

  3. On the Create table page, do the following.

    1. For Table name, specify cloudmap-table.

    2. For Partition key, specify id.

    3. Leave the rest of the default values and choose Create table.

Step 3: Create the Amazon Cloud Map data service

In this step, you create a Amazon Cloud Map service and then register the DynamoDB table created in the last step as a service instance.

  1. Open the Amazon Cloud Map console at https://console.amazonaws.cn/cloudmap/

  2. From the list of namespaces, select the cloudmap-tutorial namespace and choose View details.

  3. In the Services section, choose Create service and do the following.

    1. For Service name, enter data-service.

    2. Leave the rest of the default values and choose Create service.

  4. In the Services section, select the data-service service and choose View details.

  5. In the Service instances section, choose Register service instance.

  6. On the Register service instance page, do the following.

    1. For Instance type, select Identifying information for another resource.

    2. For Service instance id, specify data-instance.

    3. In the Custom attributes section, specify the following key-value pairs.

      • key = name, value = datatable

      • key = tablename, value = cloudmap

    4. Verify the attributes match the image below and choose Register service instance.

      
        The custom attributes for the data-service instance.

Step 4: Create an Amazon Lambda execution role

In this step, you create an IAM role that the Amazon Lambda function we create in the next step uses. You can name the role cloudmap-role and omit the permissions boundary as this IAM role is only used for this tutorial and you can delete it afterwards.

To create the service role for Lambda (IAM console)
  1. Sign in to the Amazon Web Services Management Console and open the IAM console at https://console.amazonaws.cn/iam/.

  2. In the navigation pane of the IAM console, choose Roles, and then choose Create role.

  3. For Trusted entity type, choose Amazon Web Service.

  4. For Service or use case, choose Lambda, and then choose the Lambda use case.

  5. Choose Next.

  6. Search for, and select the box next to, the PowerUserAccess policy and then choose Next.

  7. Choose Next.

  8. For Role name, specify cloudmap-tutorial-role.

  9. Review the role, and then choose Create role.

Step 5: Create the Lambda function to write data

In this step, you create a Lambda function that writes data to the DynamoDB table by using the Amazon Cloud Map API to query the Amazon Cloud Map service you created.

  1. Sign in to the Amazon Web Services Management Console and open the Amazon Lambda console at https://console.amazonaws.cn/lambda/.

  2. In the left navigation, choose Functions, Create function.

  3. On the Create function page, do the following.

    1. Select Author from scratch.

    2. For Function name, specify writefunction.

    3. For Runtime, select Python 3.12.

    4. For Architecture, select x86_64.

    5. In the Permissions section, do the following.

      1. Expand the Change default execution role option and select Use an existing role.

      2. For Existing role, use the dropdown menu to select the IAM role you created in Step 4: Create an Amazon Lambda execution role.

      3. Leave the rest of the default values and choose Create function.

    6. On the Code tab, in the Code source section, update the example code to reflect the following Python code. Take note that you're specifying the datatable custom attribute you associated with the Amazon Cloud Map service instance you created for the DynamoDB table.

      import json import boto3 import random def lambda_handler(event, context): serviceclient = boto3.client('servicediscovery') response = serviceclient.discover_instances( NamespaceName='cloudmap-tutorial', ServiceName='data-service', QueryParameters={ 'name': 'datatable' }) tablename = response["Instances"][0]["Attributes"]["tablename"] dynamodbclient = boto3.resource('dynamodb') table = dynamodbclient.Table('cloudmap-table') response = table.put_item( Item={ 'id': str(random.randint(1,100)), 'todo': event }) return { 'statusCode': 200, 'body': json.dumps(response) }
    7. Choose Deploy to update the function.

Step 6: Create the Amazon Cloud Map app service

In this step, you create an Amazon Cloud Map service and then register the Lambda write function as a service instance.

  1. Open the Amazon Cloud Map console at https://console.amazonaws.cn/cloudmap/

  2. In the left navigation, choose Namespaces.

  3. From the list of namespaces, select the cloudmap-tutorial namespace and choose View details.

  4. In the Services section, choose Create service and do the following.

    1. For Service name, enter app-service.

    2. Leave the rest of the default values and choose Create service.

  5. In the Services section, select the app-service service and choose View details.

  6. In the Service instances section, choose Register service instance.

  7. On the Register service instance page, do the following.

    1. For Instance type, select Identifying information for another resource.

    2. For Service instance id, specify write-instance.

    3. In the Custom attributes section, specify the following key-value pairs.

      • key = name, value = writeservice

      • key = function, value = writefunction

    4. Verify the attributes match the image below and choose Register service instance.

      
        The custom attributes for the write-instance instance.

Step 7: Create the Lambda function to read data

In this step, you create a Lambda function that writes data to the DynamoDB table you created.

  1. Sign in to the Amazon Web Services Management Console and open the Amazon Lambda console at https://console.amazonaws.cn/lambda/.

  2. In the left navigation, choose Functions, Create function.

  3. On the Create function page, do the following.

    1. Select Author from scratch.

    2. For Function name, specify readfunction.

    3. For Runtime, select Python 3.12.

    4. For Architecture, select x86_64.

    5. In the Permissions section, do the following.

      1. Expand the Change default execution role option and select Use an existing role.

      2. For Existing role, use the dropdown menu to select the IAM role you created in Step 4: Create an Amazon Lambda execution role.

      3. Leave the rest of the default values and choose Create function.

    6. On the Code tab, in the Code source section, update the example code to reflect the following Python code.

      import json import boto3 def lambda_handler(event, context): serviceclient = boto3.client('servicediscovery') response = serviceclient.discover_instances(NamespaceName='cloudmap-tutorial', ServiceName='data-service', QueryParameters={ 'name': 'datatable' }) tablename = response["Instances"][0]["Attributes"]["tablename"] dynamodbclient = boto3.resource('dynamodb') table = dynamodbclient.Table('cloudmap-table') response = table.get_item(Key={'id': event}) return { 'statusCode': 200, 'body': json.dumps(response) }
    7. Choose Deploy to update the function.

Step 8: Create an Amazon Cloud Map service instance

In this step, you register the Lambda read function as a service instance in the app-service service you previously created.

  1. Open the Amazon Cloud Map console at https://console.amazonaws.cn/cloudmap/

  2. In the left navigation, choose Namespaces.

  3. From the list of namespaces, select the cloudmap-tutorial namespace and choose View details.

  4. In the Services section, select the app-service service and choose View details.

  5. In the Service instances section, choose Register service instance.

  6. On the Register service instance page, do the following.

    1. For Instance type, select Identifying information for another resource.

    2. For Service instance id, specify read-instance.

    3. In the Custom attributes section, specify the following key-value pairs.

      • key = name, value = readservice

      • key = function, value = readfunction

    4. Verify the attributes match the image below and choose Register service instance.

      
        The custom attributes for the read-instance instance.

Step 9: Create a development environment

Amazon Cloud9 is an integrated development environment (IDE) managed by Amazon. The Amazon Cloud9 IDE provides the software and toooling needed for dynamic programming. In this step, we create an Amazon Cloud9 environment and configure it with the Amazon SDK for Python (Boto3) which you will to program with the Amazon API.

  1. Sign in to the Amazon Web Services Management Console and open the Amazon Cloud9 console at https://console.amazonaws.cn/cloud9/.

  2. In the left navigation menu, select My environments and then choose Create environment.

  3. On the Create environment page, do the following to create your development environment.

    1. For Name, use cloudmap-tutorial.

    2. For Environment type, select New EC2 instance.

    3. For Instance type, select t2.micro.

    4. For Platform, use the drop down menu to select Ubuntu Server 22.04 LTS.

    5. Leave the rest of the default selections and choose Create.

  4. Once your Amazon Cloud9 environment is created, select the cloudmap-tutorial environment and choose Open in Cloud9. This opens the development environment in a new tab and provides you with a bash shell to work with.

    Important

    If you have issues opening your Amazon Cloud9 environment, see Amazon Cloud9 troubleshooting: Can't open an environment in the Amazon Cloud9 User Guide.

  5. Using the bash shell, run the following commands to configure the environment.

    1. Update the environment.

      sudo apt-get -y update
    2. Verify that python3 is installed.

      python3 --version
    3. Install the Boto3 package in the environment.

      sudo apt install -y python3-boto3

Step 10: Create a frontend client

Using the Amazon Cloud9 development environment created in the previous step, you create a frontend client that uses code that discovers the services you configured in Amazon Cloud Map and makes calls to these services.

  1. Sign in to the Amazon Web Services Management Console and open the Amazon Cloud9 console at https://console.amazonaws.cn/cloud9/.

  2. In the left navigation menu, select My environments and then select your cloudmap-tutorial environment and choose Open in Cloud9.

  3. In the Amazon Cloud9 environment, in the File menu, choose New file which creates a file named Untitled1.

  4. In the Untitled1 file, copy and paste the following code. This code discovers the Lambda function to write data by searching for the custom attribute name=writeservice in the app-service service. The name of the Lambda function is returned which is responsible for writing data to the DynamoDB table. Then the Lambda function is invoked, passing a sample payload.

    import boto3 serviceclient = boto3.client('servicediscovery') response = serviceclient.discover_instances(NamespaceName='cloudmap-tutorial', ServiceName='app-service', QueryParameters={ 'name': 'writeservice' }) functionname = response["Instances"][0]["Attributes"]["function"] lambdaclient = boto3.client('lambda') resp = lambdaclient.invoke(FunctionName=functionname, Payload='"This is a test data"') print(resp["Payload"].read())
  5. From the File menu, choose Save As... and save the file as writeclient.py.

  6. From the bash shell in your Amazon Cloud9 environment, use the following command to run the Python code.

    python3 writeclient.py

    The output should be a 200 response, similar to the following.

    b'{"statusCode": 200, "body": "{\\"ResponseMetadata\\": {\\"RequestId\\": \\"Q0M038IT0BPBVBJK8OCKK6I6M7VV4KQNSO5AEMVJF66Q9ASUAAJG\\", \\"HTTPStatusCode\\": 200, \\"HTTPHeaders\\": {\\"server\\": \\"Server\\", \\"date\\": \\"Wed, 06 Mar 2024 22:46:09 GMT\\", \\"content-type\\": \\"application/x-amz-json-1.0\\", \\"content-length\\": \\"2\\", \\"connection\\": \\"keep-alive\\", \\"x-amzn-requestid\\": \\"Q0M038IT0BPBVBJK8OCKK6I6M7VV4KQNSO5AEMVJF66Q9ASUAAJG\\", \\"x-amz-crc32\\": \\"2745614147\\"}, \\"RetryAttempts\\": 0}}"}'
  7. To verify the write was successful in the previous step, create a read client.

    1. Sign in to the Amazon Web Services Management Console and open the DynamoDB console at https://console.amazonaws.cn/dynamodb/.

    2. In the left navigation pane, choose Tables.

    3. From the list of tables, select your cloudmap-table and use the Actions menu to choose Explore items.

    4. In the Items returned section, take note of the numerical value in the id(String) column.

      The following shows an example, where the id(String) value is 98.

      
        The id(String) value of a DynamoDB entry.
    5. In the Amazon Cloud9 environment, in the File menu, choose New file which creates a file named Untitled1.

    6. In the Untitled1 file, copy and paste the following code. Replace the Payload value with the id (String) value from your DynamoDB table in the previous step. This code reads from the table and will return the value that you wrote to the table in the previous step.

      import boto3 serviceclient = boto3.client('servicediscovery') response = serviceclient.discover_instances(NamespaceName='cloudmap-tutorial', ServiceName='app-service', QueryParameters={ 'name': 'readservice' }) functionname = response["Instances"][0]["Attributes"]["function"] lambdaclient = boto3.client('lambda') resp = lambdaclient.invoke(FunctionName=functionname, InvocationType='RequestResponse', Payload='"98"') print(resp["Payload"].read())
    7. From the File menu, choose Save As... and save the file as readclient.py.

    8. From the bash shell in your Amazon Cloud9 environment, use the following command to run the Python code.

      python3 readclient.py

      The output should look similar to the following.

      b'{"statusCode": 200, "body": "{\\"Item\\": {\\"id\\": \\"98\\", \\"todo\\": \\"This is a test data\\"}, \\"ResponseMetadata\\": {\\"RequestId\\": \\"JSO5DLRGF0JUPQN4NCH369ABMBVV4KQNSO5AEMVJF66Q9ASUAAJG\\", \\"HTTPStatusCode\\": 200, \\"HTTPHeaders\\": {\\"server\\": \\"Server\\", \\"date\\": \\"Wed, 06 Mar 2024 23:03:38 GMT\\", \\"content-type\\": \\"application/x-amz-json-1.0\\", \\"content-length\\": \\"61\\", \\"connection\\": \\"keep-alive\\", \\"x-amzn-requestid\\": \\"JSO5DLRGF0JUPQN4NCH369ABMBVV4KQNSO5AEMVJF66Q9ASUAAJG\\", \\"x-amz-crc32\\": \\"3104232745\\"}, \\"RetryAttempts\\": 0}}"}'

Step 11: Clean up the resources

Once you have completed the tutorial, to ensure you don't incur any additional charges, you can delete the resources. Amazon Cloud Map requires that you clean them up in reverse order, the service instances first, then the services, and finally the namespace. The following steps walk you through cleaning up the Amazon Cloud Map, Lambda, DynamoDB, and Amazon Cloud9 resources used in this tutorial.

To delete the Amazon Cloud9 resource
  1. Sign in to the Amazon Web Services Management Console and open the Amazon Cloud9 console at https://console.amazonaws.cn/cloud9/.

  2. In the left navigation menu, select My environments.

  3. Select your cloudmap-tutorial environment and choose Delete.

  4. Confirm the deletion by typing Delete and then choose Delete.

To delete the Lambda functions
  1. Sign in to the Amazon Web Services Management Console and open the Amazon Lambda console at https://console.amazonaws.cn/lambda/.

  2. In the left navigation, choose Functions.

  3. Select both the writefunction and readfunction functions.

  4. From the Actions menu, choose Delete.

  5. Confirm the deletion by typing delete and then choose Delete.

To delete the DynamoDB table
  1. Sign in to the Amazon Web Services Management Console and open the DynamoDB console at https://console.amazonaws.cn/dynamodb/.

  2. In the left navigation pane, choose Tables.

  3. Select the cloudmap-table table and choose Delete.

  4. Confirm the deletion by typing confirm and then choose Delete.

To delete the Amazon Cloud Map resources
  1. Sign in to the Amazon Web Services Management Console and open the Amazon Cloud Map console at https://console.amazonaws.cn/cloudmap/.

  2. From the list of namespaces, select the cloudmap-tutorial namespace and choose View details.

  3. On the namespace details page, from the list of services, select the data-service service and choose View details.

  4. In the Service instances section, select the data-instance instance and choose Deregister.

  5. Using the breadcrumb at the top of the page, select cloudmap-tutorial.com to navigate back to the namespace detail page.

  6. On the namespace details page, from the list of services, select the data-service service and choose Delete.

  7. Repeat steps 3-6 for the app-service service and the write-instance and read-instance service instances.

  8. In the left navigation, choose Namespaces.

  9. Select the cloudmap-tutorial namespace and choose Delete.