• 4 min read

Amazon Web Services (AWS): Using of AWS Cloud Control API


Contents


blog_image

Introduction

No one building of well-functional APIs is not without four basic functions: Create, Read, Update, and Delete (CRUD). The CRUD paradigm is common in constructing web applications, because it provides a memorable framework for reminding developers of how to construct full, usable models.


Recently Amazon announced the availability of AWS Cloud Control API, a standard set of APIs to Create, Read, Update and Delete (CRUD) resources across some AWS Services. The count of supported services will be increasing. For instance Amazon promised to add support for Elastic Compute Cloud and Amazon Simple Storage Service in the coming months.


Fortunately, AWS Lambda is now supported, so let’s test a new service with it. We will try to implement the CRUD operations with lambda function and find out if the Cloud Control API is a really useful service?

Create Lambda Function

To create an AWS Lambda function, we have to create an index.py handler, zip it, and upload the zip file to one of the S3 buckets. The bucket has to be in the same AWS Region where we will create the Lambda function.


import boto3
import json

s3_client = boto3.client('s3')
dynamodb_client = boto3.client('dynamodb')


def lambda_handler(event, context):
   buckets = s3_client.list_buckets().get('Buckets')
   list_of_buckets = []
   for bucket in buckets:
       name = bucket.get('Name')
       list_of_buckets.append(name)

   tables = dynamodb_client.list_tables().get('TableNames')
   return {
       'statusCode': 200,
       "body": json.dumps(
           {
               'buckets': list_of_buckets,
               'tables': tables
           }
       ),
   }
zip index.zip index.py
aws s3 cp index.zip s3://cloud-control-test/index.zip

Then we call the create-resource API, with the same set of arguments as required by the corresponding CloudFormation resource.


aws cloudcontrol create-resource

--type-name AWS::Lambda::Function
--desired-state '{
    "Code":{"S3Bucket":"cloud-control-test","S3Key":"index.zip"},
    "FunctionName":"Cloud-Control-Test",
    "Role":"arn:aws:iam::938668680897:role/LambdaAdminAccessRole",
    "Runtime":"python3.8",
    "Handler":"index.lambda_handler"
}'


{
   "ProgressEvent": {
       "TypeName": "AWS::Lambda::Function",
       "Identifier": "Cloud-Control-Test",
       "RequestToken": "0adf6a52-07a0-44fe-bed1-f518a339a908",
       "Operation": "CREATE",
       "OperationStatus": "IN_PROGRESS",
       "EventTime": "2021-11-05T10:48:14.062000+02:00"
   }
}

Get Lambda Function

In this step we can check our function by calling the get-resource API. This action returns information about an existing resource.


aws cloudcontrol get-resource

--type-name AWS::Lambda::Function
--identifier Cloud-Control-Test

{
    "TypeName": "AWS::Lambda::Function",
    "ResourceDescription": {
        "Identifier": "Cloud-Control-Test",
        "Properties":
            "{
                \"Role\":\"arn:aws:iam::938668680897:role/LambdaAdminAccessRole\",
                \"FileSystemConfigs\":[],
                \"FunctionName\":\"Cloud-Control-Test\",
                \"MemorySize\":128,
                \"Runtime\":\"python3.8\",
                \"Description\":\"\",
                \"TracingConfig\":{\"Mode\":\"PassThrough\"},
                \"Timeout\":3,
                \"PackageType\":\"Zip\",
                \"Handler\":\"index.lambda_handler\",
                \"Arn\":\"arn:aws:lambda:us-east-2:938668680897:function:Cloud-Control-Test\",
                \"Architectures\":[\"x86_64\"]
        }"
    }
}

So we can invoke the Lambda function to ensure it works as expected.


aws lambda invoke --function-name Cloud-Control-Test out.txt && cat out.txt && rm out.txt

{
   "StatusCode": 200,
   "ExecutedVersion": "$LATEST"
}

{
"statusCode": 200,
"body": "{
    \"buckets\":
        [\"a2itestbucket\", \"rappa-w69r7lpqg\", \"wappa-yhc1hphqc\"],
    \"tables\":
        [\"Test2API\", \"Test_table\", \"lambda-test-dev-Table_jobs\"]
    }"
}

Update Lambda Function

Now, we will try to update one parameter of our function, for example Runtime.


aws cloudcontrol update-resource

--type-name AWS::Lambda::Function
--identifier Cloud-Control-Test
--patch-document "[{
    \"op\":\"test\",
    \"path\":\"/Runtime\",
    \"value\":\"python3.8\"
}]"


{
    "ProgressEvent": {
        "TypeName": "AWS::Lambda::Function",
        "Identifier": "Cloud-Control-Test",
        "RequestToken": "7b17fe21-fd0a-40f2-909b-c7302bdfe60d",
        "Operation": "UPDATE",
        "OperationStatus": "SUCCESS",
        "EventTime": "2021-11-05T11:00:18.456000+02:00",
        "ResourceModel":
            "{
                \"Role\":\"arn:aws:iam::938668680897:role/LambdaAdminAccessRole\",
                \"FileSystemConfigs\":[],
                \"FunctionName\":\"Cloud-Control-Test\",
                \"MemorySize\":128,\"Runtime\":\"python3.8\",
                \"Description\":\"\",
                \"TracingConfig\":{\"Mode\":\"PassThrough\"},
                \"Timeout\":3,
                \"PackageType\":\"Zip\",
                \"Handler\":\"index.lambda_handler\",
                \"Arn\":\"arn:aws:lambda:us-east-2:938668680897:function:Cloud-Control-Test\",
                \"Architectures\":[\"x86_64\"]
        }"
    }
}

As we can see, the test operation works without any problem. So let’s try to replace the value:


aws cloudcontrol update-resource

--type-name AWS::Lambda::Function
--identifier Cloud-Control-Test
--patch-document "[{
    \"op\":\"replace\",
    \"path\":\"/Runtime\",
    \"value\":\"python3.9\"
}]"


An error occurred (ValidationException) when calling the UpdateResource operation:
Model validation failed (#: required key [Code] not found)

This time we are getting an error which says that we have to add a Code key to our request. Let’s try to do it:


aws cloudcontrol update-resource

--type-name AWS::Lambda::Function
--identifier Cloud-Control-Test
--patch-document "[{
    \"op\":\"replace\",
    \"path\":\"/Runtime\",
    \"Code\": {\"RepositoryType\": \"S3\",
    \"Location\": \"$Location\"},
    \"value\":\"python3.9\"
}]"


An error occurred (ValidationException) when calling the UpdateResource operation:
Invalid PatchDocument: #/0: extraneous key [Code] is not permitted

We are getting another one error which says that using this key is not permitted.


Surfing the net in an effort to solve this problem I couldn’t find any useful information. This is due to the service being launched recently and probably it’s a little bug that will be fixed in the near future.

Delete Lambda Function

When finished, we delete the Lambda function using Cloud Control API:


aws cloudcontrol delete-resource

--type-name AWS::Lambda::Function
--identifier Cloud-Control-Test

{
    "ProgressEvent": {
        "TypeName": "AWS::Lambda::Function",
        "Identifier": "Cloud-Control-Test",
        "RequestToken": "0fe0190d-4102-4763-afb7-68f9903cf21e",
        "Operation": "DELETE",
        "OperationStatus": "IN_PROGRESS",
        "EventTime": "2021-11-05T11:53:48.195000+02:00"
    }
}

Conclusion

To sum up, Amazon created a convenient tool to work with resources. A lot of infrastructure as code products that use AWS Services might be significantly simplified by Cloud Control API. To date, further refinement of the cover is required. A list of supported services is not large enough and some bugs inhibit the full realization of its benefits. Well, let’s hope Amazon will concentrate on improving the AWS Cloud Control API!

Amazon Web Services (AWS): Using of AWS Cloud Control API

Anastasiia Tokareva

Software Engineer