Amazon API Gateway

In this lab you will experiment the Amazon API Gateway.

This is an introductory (100 level) lab to help you to explore API Gateway.

IMPORTANT: Be careful with copy-and-paste. Some hidden HTML characters may be copied to the AWS Console, resulting in unexpected errors.

Prerequisites

You need:

Context

We are going to create an API that will consume services from AWS Systems Manager (SSM), using the Parameter Store feature.

Your API will consume the configuration for a system, stored on the Parameter Store. We are considering that all parameters for a certain system will have the form /systems/<systemName>/config, where <systemName> is, obvioulsy, the name of the system to which we want to retrieve the configuration.

So, the idea for this API is to retrieve all the configuration for a system that you specify in the query string. The purpose is to design an API that works similarly to what's provided here:

REQUEST:
https://<api>/getconfig?system=nameOfSystem

RESPONSE:
{
data : {
<configKey1> : <configKey1Value> ,
<configKey2> : <configKey2Value> ,
...
}
}

On this lab, if you are sharing a single AWS Account and region with other users, we recommend you to include your initials as a prefix on the name of the resources. This is shown as <prefix> on the instructions. You can disregard that if you are alone in an AWS Account and region.

Task: Creating the parameters for your hypothetical system

  1. Visit the Systems Manager page on your AWS console.
  2. At the menu on the left, select Parameter Store.
  3. Click on Create parameter.
  4. For Name, input /systems/<prefix>system01/config.
  5. You use Description to provide an informative description about the purpose of this parameter.
  6. For Tier, select Standard. We are willing to run under free tier.
  7. Type is String for our case.
  8. For Value, input the following JSON, as an example:
    {
      "url" : "https://www.amazon.com"
    }
    Your parameter creation window will be similar to the following one:
  9. Click on Create parameter.

Task. Creating an IAM role for your API

Your API will need to have the proper permissions to access the required services - in this case, Systems Manager. To accomplish this, we will create a role that will give to our API the permissions to consume the parameters from SSM/Parameter Store.
  1. Visit the IAM page on the AWS account console.
  2. On the left, select Roles.
  3. Click on Create role.
  4. Click on AWS Service, then choose API Gateway, and then click on the button Next: Permissions.
    The policy AmazonAPIGatewayPushToCloudWatchLogs will be automatically added. This policy is required for your API to be able to push logs to CloudWatchLogs.
  5. Click on Next:Tags. At this moment we will not define tags, but this is a very handy resource from a governance perspective.
  6. Click on Next: Review.
  7. On the next page, you will define a role name for your role. Set it up as <prefix>SystemConfigAPI, and for description input some clarifying description for the role.
  8. Click on Create Role.
  9. On the top, you will will see a message informing you that the role was created.


  10. Click on the role name. You will be taken to the role summary page similar to the one below.


  11. Let's add an inline policy that will grant our API access to Systems Manager.
    1. Click on Add inline policy. The window to create the policy will show up.
    2. For Service, select Systems Manager.
    3. For Actions, choose GetParameter.
    4. For Resources, click on Add ARN.
      1. For region, include the region where you are working on (example: eu-west-2).
      2. For account, input your account Id.You can get your account id by visiting the option My Account at your AWS console.
      3. For Fully qualified parameter name, enter systems/*/config. This means that you will be able to retrieve the configuration for all systems. Suppose we are retrieving the config for a system named "ticketing", then the parameter will be systems/ticketing/config.
      4. Click on Add.
    5. Click on Review Policy.
    6. Give an informative name for the policy, like SystemsManagerPermissions.
    7. Click on Create Policy.

See that the policy was added to your role. As this role will be used to define the permissions for our API, take note of the role ARN.

Explore the role configuration, to get more awareness about the role structure.

Task: Creating the API

  1. Visit the API Gateway home page.
  2. Click on the Create the API button
    1. Select REST
    2. Under the section Create new API, select New API
    3. For API name, input <prefix>SystemConfigTracker
    4. For Description, input This API tracks the configuration of all systems under our organization
    5. For endpoint, choose Regional.
    6. Click on Create API. You will be taken to a page where you will be able to configure the API.
  3. Click on the drop-down button Actions, and click on Create Resource. A page titled New Child Resource will show up.
    1. For Resource Name, input getconfig
    2. Leave all the other options as they are, and click on Create Resource
  4. Creating the HTTP method
    1. Select the /getconfig resource that you just created
    2. Click on the drop-down button Actions, and click on Create Method. A drop-down list will appear below /getconfig
    3. Select GET on that list, and click on the small check button to confirm. You will be taken to a page where you will configure the integration for that method
  5. On the page titled /getconfig - GET - Setup
    1. For Integration type, select AWS Service.
    2. For AWS Region, select the same region you are working at. Tip: You can check it by looking at the URL on your browser
    3. For AWS Service, select Simple Systems Management (SSM).
    4. Leave AWS Subdomain blank.
    5. For HTTP method, select POST. We are converting a GET request to a POST request, because the Systems Manager request for GetParameter is a POST.
    6. For Action Type, select Use path override, and then for Path override (optional), input a forward slash  /
    7. For Execution Role, input the IAM role that you created in the previous task
    8. Leave everything else as it is, and click on Save. You will be taken to a page where you will configure the integration for this method.
    9. We will configure the API Gateway integration with SSM. Click on Integration Request
      1. Scroll down to HTTP Headers
        1. Click on Add header, and let's configure the SSM method that we want to invoke
          1. For Name, input X-Amz-Target
          2. For Mapped from, input 'AmazonSSM.GetParameter'. Don't forget of including the single quotes.
          3. Click on the small button at the right, to confirm
        2. Click on Add header again, and lets configure the content type expected by the SSM API
          1. For Name, input Content-Type
          2. For Mapped from, input 'application/x-amz-json-1.1'. Same as before, don't forget of including the single quotes.
          3. Click on the small button at the right, to confirm
      2. Scroll down to Mapping Templates. We will configure a mapping template for a testing purpose. A little later we will get back here and configure a transformation by getting data from the query string.
        1. Click on Mapping Templates
        2. For Request body passthrough, select When there are no templates defined (recommended)
        3. Click on Add mapping template
        4. For Content-Type, input application/json, and then click on the icon to confirm. A text-box will appear so you can input the mapping template.
        5. For testing purposes, input the following text. Don't forget of replacing <prefix> with the prefix that you have defined for your parameter
        6. {
          "Name" : "/systems/<prefix>system01/config" }
        7. Click on Save
      3. Scroll up, and click on Method Execution, to get back to the integration configuration. You will see a vertical bar labeled as Test at the left
    10. Testing the API
      1. Click on the vertical bar labeled as Test. You will be taken to the API Gateway test page
      2. Scroll down, and you will see a Test button. Click on it.
      3. If everything went well, you will see a Response Body as the one below
      4. {
          "Parameter": {
            "ARN": "arn:aws:ssm:<region>:<account>:parameter/systems/<prefix>system01/config",
            "LastModifiedDate": 1557241970.82,
            "Name": "/systems/<prefix>system01/config",
            "Type": "String",
            "Value": "{\"url\":\"https://www.amazon.com\"}",
            "Version": 4
          }
        }
    11. Fine-tunning the integration
      Let us improve our integration, by (1) getting the server name from the query string,  then inserting it inside the request that is submitted to Systems Manager, and finally (2) let's provide a clean response for the requestor
      1. Including the query string value for the key "system" into the integration request
        1. Click on Integration Request
        2. Scroll down to Request body passthrough, and replace the template with the following content
        3. {
             "Name" : "/systems/$input.params('system')/config"
          }
        4. Click on Save.
        5. Scroll up and click on Method Execution. Let's test it.
        6. Click on the vertical bar labeled as Test
        7. Go to the section Query Strings, and fill it with the name of the system that you created on System Management. Don't forget of replacing <prefix>system01 with the name that you choose.

        8. Test it by clicking on the button Test down on the page.
        9. Explore the details of the response.
        10. Test it with a different, inexistent parameter name (like system=inexistent). Check the response, including the HTTP response code.
      2. Now, let's clean the response for the requestor
        1. If you are still on the testing page, scroll to the top and click on Method Execution to get back to the /getconfig - GET - Method Execution configuration page.
        2. Click on Integration Response.The following page will be shown to you (with some sections collapsed. We will work on one of them on the next steps).
        3. Select the row related to the 200 Method response status.
        4. Scroll down to the section Mapping Templates, and expand it.
        5. On Content-type, click on application/json, and add the following mapping template to the template editor
        6. #set($inputRoot=$input.path('$'))
          #if ($inputRoot.Parameter.Value && $inputRoot.Parameter.Value!="")
          {
            "data" : $input.path('$').Parameter.Value
          }
          #end
        7. Click on Save.
        8. Scroll to the top, and click on the Method Execution link. Test the API as you did before.
        9. For the existing parameter, you are expected to get an answer as shown one bellow
        10. {
            "data": {
              "url": "https://www.amazon.com"
            }
          }

    Task: Deploying the API

    The API that you just created is not available externally. To make it callable by users and other systems - the clients of the API - you need to deploy it. To deploy an API, you create an API deployment and associate it with a stage. Each stage is a snapshot of the API and is made available for client apps to call. You can read more about it here.

    1. Click on the drop-down button Actions, and select Deploy API.
    2. You need to deploy the API on a stage. As we don't have one yet, lets create a prod stage.
    3. Click on Deploy. You will be going to be redirected to a page where you have  the configuration for the stage. At the top of the page you will see the URL for your API deployment.

    4. Copy the URL. You will need it.

    Task: Consuming the API

    We will use CURL to test the API.

    1. Copy the Invoke URL which is presented at the top of the deployment that we've just created.
    2. Go the terminal (console, command-line) on your computer or Cloud9 environment.
    3. Execute the following command
      1. Don't forget to replace <prefix> with the one that you choose when you created the SSM parameter for your system
    $ curl  https://<api stage deployment URL>/getconfig?system=<prefix>system01

    Task: Explore a bit more your API responses

    Test your API with a non-existent parameter, both on the console and using CURL. Check the response code, and the response body. Do you think that this is properly configured? Do you think that it's simple to configure a better response for the API clients?

    Additional considerations

    The API is not secure. For deploying an API in production, and exposing it publicly, you should consider on implementing the proper access and throttling controls.

    Finishing the lab

    You have finished this lab.

    Now, you can delete all the resources from your account (unless guided differently by the presenter):

    1. Go to SSM, Parameter Store, and delete the resource that you've created.
    2. Go to IAM, and delete the role.
    3. On API Gateway, delete your API.