AppConfig & Lambda Integration

At this point we have created a Lambda with an API Gateway trigger that returns our array of JSON objects. In this section of the lab, we will modify our API Gateway Lambda to utilize the boolEnableLimitResults and intResultLimit properties of our configuration document to enable a new feature that will limit the number of results returned by API Gateway as well as utilize the value of intResultLimit to determine how many results to return.

We will start with updating our Lambda configuration to utilize the AWS AppConfig integration with Lambda extensions and then modify our Lambda code to retrieve the configuration data from the AWS AppConfig Lambda extension and extract from it the boolean value for boolEnableLimitResults. We will use that value as a means to turn on or off our filtering feature.

Recall that our configuration document that we stored in the hosted configuration store and subsequently deployed looks like this:

{
   "boolEnableLimitResults": false,
   "intResultLimit": 0
} 

Note that boolEnableLimitResults is set to false. This is common practice to deploy a feature or block of new code disabled by default. Once successfully deployed, we can turn it on by changing the value of boolEnableLimitResults to true, observe for errors and turn it off if we encounter any errors. This helps avoid a hotfix on production, for example.

Modify IAM Lambda Execution Policy to Allow Lambda to Call AppConfig GetConfiguration API

In order to enable our API Gateway Lambda to integrate with AppConfig, we need to add permissions to the Lambda to access our AppConfig Application.

Use the following procedure to add the necessary permissions to the Lambda execution policy to allow our API Gateway Lambda to call the AppConfig GetConfiguration API.

  1. Return to the browser tab with your Lambda or Visit the Lambda Console and select AppConfigLabAPIGatewayLambda from the list of functions.
  2. Select the Permissions tab and click on the Role name in the Execution role section. This will open in a new browser window or tab our Lambda execution role in the IAM console.
  3. In the Permission policies section, select the policy attached to this role which should be prefixed with AWSLambdaBasicExecutionRole-.
  4. Select Edit policy and then select the JSON tab.
  5. Add the following to the policy and replace YOUR_ACCOUNT_NUMBER with your AWS Account number. If you do not know your Account Number, click here for instructions on how to obtain it.
    {
        "Effect": "Allow",
        "Action": "appconfig:GetConfiguration",
        "Resource": "arn:aws:appconfig:us-east-1:YOUR_ACCOUNT_NUMBER:*"
    }
    
  6. The policy should resemble the following. AppConfig Lambda Consumer Policy
  7. Select Review policy and then Save changes.

Configure AWS AppConfig Lambda extension

We will utilize the AWS AppConfig integration with Lambda extensions to retrieve the configuration data from the local configuration cache. The following diagram shows how it works.

AppConfig Lambda Extension

  1. You configure the AWS AppConfig Lambda extension as a layer of your Lambda function.
  2. The extension receives the GetConfiguration request from the function and checks the local cache. The local cache is an HTTP server.
  3. The cache is empty so the extension passes the call to the SDK, which calls the AWS AppConfig service.
  4. Upon receiving the configuration from the service, the extension stores it in the local cache and passes it to the Lambda function.
  5. The extension locates and returns subsequent calls to GetConfiguration from the local cache. The AWS AppConfig Lambda extension manages configuration caching and updating so the configuration persists between Lambda handler invocations. When a configuration is needed, the Lambda handler makes a request to the AWS AppConfig Lambda extension instead of the AWS AppConfig service. The configuration is cached locally and returns much faster, which reduces the cost of using AWS Lambda and AWS AppConfig.

The next time the Lambda function is invoked, the extension checks the elapsed time since it retrieved a configuration from AWS AppConfig. If the elapsed time is greater than the poll interval, the extension retrieves the latest configuration from AWS AppConfig and updates the cache.

Visit AWS AppConfig integration with Lambda extensions documentation for more information.

Use the following procedure to configure the AWS AppConfig integration with Lambda extensions:

  1. Return to the browser tab with your Lambda or Visit the Lambda Console and select AppConfigLabAPIGatewayLambda from the functions list.
  2. Select the Configuration tab and locate the Designer section at the top.
  3. Select Layers, then Add a layer.
  4. Select Specify an ARN from the Choose a layer option.
  5. Enter arn:aws:lambda:us-east-1:027255383542:layer:AWS-AppConfig-Extension:1 in the Specify and ARN field. This ARN represents the AppConfig Lambda extension with the name of AWS-AppConfig-Extension for the AWS Region us-east-1.
  6. Select Add to finish adding the layer to our Lambda function and return you to the Configuration tab.
  7. Next, locate the Environment variables section on the Configuration tab.
  8. Choose Edit, then Add environment variable.
  9. Enter AWS_APPCONFIG_EXTENSION_HTTP_PORT in the Key field and 2772 in the **Value field.
  10. Select Add environment variable again.
  11. Enter AWS_APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDS in the Key field and 45 in the **Value field.
  12. Select Add environment variable again.
  13. Enter AWS_APPCONFIG_EXTENSION_POLL_TIMEOUT_MILLIS in the Key field and 3000 in the **Value field.
  14. Select Save to finish adding these environment variables and return to the Configuration tab.

The AWS_APPCONFIG_EXTENSION_HTTP_PORT environment variable specifies the port on which the local HTTP server that hosts the extension runs. The default value is 2772.

The AWS_APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDS environment variable controls how often the extension polls AWS AppConfig for an updated configuration in seconds. The default value is 45 seconds.

The AWS_APPCONFIG_EXTENSION_POLL_TIMEOUT_MILLIS environment variable controls the maximum amount of time the extension waits before retrieving configurations from the cache in milliseconds. The default value is 3000

Modify Lambda Code to Call AppConfig GetConfiguration API

Use the following procedure to integrate AppConfig with our API Gateway Lambda.

  1. Return to the browser tab with your Lambda or Visit the Lambda Console and select AppConfigLabAPIGatewayLambda from the functions list.
  2. Select the Configuration tab and replace the code in the Function code with the following.
    const http = require('http');
    
    exports.handler = async (event) => {
      
      const res = await new Promise((resolve, reject) => {
        http.get(
          "http://localhost:2772/applications/AppConfigLab/environments/AppConfigLabAPIGatewayDevelopment/configurations/AppConfigLabHostedConfigurationProfile", 
          resolve
        );
      });
      
      let configData = await new Promise((resolve, reject) => {
        let data = '';
        res.on('data', chunk => data += chunk);
        res.on('error', err => reject(err));
        res.on('end', () => resolve(data));
      });
    
      let result = getServices();
      
      const parsedConfigData = JSON.parse(configData);
             
      // add result limit code here
    
      const response = {
        statusCode: 200,
        body: parsedConfigData,
      };
      return response;
    };
    
    function getServices() {
      return [
        {
          name: 'AWS AppConfig'
        },
        {
          name: 'Amazon SageMaker Studio'
        },
        {
          name: 'Amazon Kendra'
        },
        {
          name: 'Amazon CodeGuru'
        },
        {
          name: 'Amazon Fraud Detector'
        },
        {
          name: 'Amazon EKS on AWS Fargate'
        },
        {
          name: 'AWS Outposts'
        },
        {
          name: 'AWS Wavelength'
        },
        {
          name: 'AWS Transit Gateway'
        },
        {
          name: 'Amazon Detective'
        }
      ];
    }
    
  3. Select Deploy.

Observe the code and note that we first added code to require http which is an HTTP interface built in to Node.js.

const http = require('http');

We then added code to call the AWS AppConfig Lambda extension. Note that the hostname for our http API call is localhost which illustrates the call to the local cache created by the AWS AppConfig Lambda extension. The port is set to 2772 which was specified in our Lambda environment variable AWS_APPCONFIG_EXTENSION_HTTP_PORT.

The url format http://localhost:2772/applications/APPLICATION_NAME/environments/ENVIRONMENT_NAME/configurations/CONFIGURATION_NAME where APPLICATION_NAME is AppConfigLab - the name we used when we created our AWS AppConfig Application earlier in the lab. Similarly, ENVIRONMENT_NAME is AppConfigLabAPIGatewayDevelopment, the Environment name we used, and CONFIGURATION_NAME is AppConfigLabHostedConfigurationProfile, the name chosen for our Configuration profile.

const res = await new Promise((resolve, reject) => {
  http.get("http://localhost:2772/applications/AppConfigLab/environments/AppConfigLabAPIGatewayDevelopment/configurations/AppConfigLabHostedConfigurationProfile", resolve);
});

let configData = await new Promise((resolve, reject) => {
  let data = '';
  res.on('data', chunk => data += chunk);
  res.on('error', err => reject(err));
  res.on('end', () => resolve(data));
});

Lastly, we changed the response to actually include the parsed configuration data just to test the integration all the way through. We can expect that if we perform a test execution of our API Gateway or Lambda that the body will now contain the actual configuration data we included in our hosted configuration instead of a list of AWS Services.

const parsedConfigData = JSON.parse(configData);
              
// add result limit code here

const response = {
  statusCode: 200,
  body: parsedConfigData,
};

Use the following procedure to verify the Lambda can retrieve the configuration.

  1. Toggle to your API Gateway browser tab or window or visit API Gateway and select AppConfigLabAPI from the list.
  2. Select the GET method under the root resources, then select TEST.
  3. Select Test and verify that the Response Body from the test execution appears as follows.
{
  "statusCode": 200,
  "body": {
    "boolEnableLimitResults": false,
    "intResultLimit": 0
  }
}

That’s it! We have now successfully configured the permissions necessary for Lambda to retrieve our AppConfig configuration data and modified our Lambda code to retrieve the data and return it in the body of our response as a means to test the integration between Lambda and AppConfig.

Next up in the lab, we will modify our Lambda code to use the boolEnableLimitResults value of our configuration data to enable a new feature that will allow us to the limit the number objects returned by the API. Additionally, we will use the value of the intResultLimit property to configure the number of items to return in the API response when the feature is enabled.