aws cdk lambda, appconfig typescript example please?

4.8k Views Asked by At

Can anyone provide or point at an AWS-CDK/typescript example provisioning an AWS AppConfig app/env/config consumed by a lambda please? Could not find anything meaningful online.

2

There are 2 best solutions below

1
On

I have no experience with AWS AppConfig. But I would start here and here

3
On

A little late to this party, If anyone is coming to this question, looking for a quick answer, here you go:

AppConfig Does Not Have Any Official L2 Constructs

  • This means that one has to work with L1 constructs currently vended here
  • This is ripe for someone authoring an L2/L3 construct (I am working on vending this custom construct soon - so keep an eye out on updates here).
  • This does not mean its hard to use AppConfig in CDK, its just that unlike L2/L3 constructs, we have to dig deeper into setting AppConfig up reading their documentation.

A Very Simple Example (YMMV)

Here is a custom construct I have to setup AppConfig:

import {
  CfnApplication,
  CfnConfigurationProfile,
  CfnDeployment,
  CfnDeploymentStrategy,
  CfnEnvironment,
  CfnHostedConfigurationVersion,
} from "aws-cdk-lib/aws-appconfig";
import { Construct } from "constructs";

// 1. https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appconfig-readme.html - there are no L2 constructs for AppConfig.
// 2. https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-working.html- this the CDK code from this console setup guide.
export class AppConfig extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    // create a new app config application.
    const testAppConfigApp: CfnApplication = new CfnApplication(
      this,
      "TestAppConfigApp",
      {
        name: "TestAppConfigApp",
      }
    );

    // you can customize this as per your needs.
    const immediateDeploymentStrategy = new CfnDeploymentStrategy(
      this,
      "DeployStrategy",
      {
        name: "ImmediateDeployment",
        deploymentDurationInMinutes: 0,
        growthFactor: 100,
        replicateTo: "NONE",
        finalBakeTimeInMinutes: 0,
      }
    );

    // setup an app config env
    const appConfigEnv: CfnEnvironment = new CfnEnvironment(
      this,
      "AppConfigEnv",
      {
        applicationId: testAppConfigApp.ref,
        // can be anything that makes sense for your use case.
        name: "Production",
      }
    );

    // setup config profile
    const appConfigProfile: CfnConfigurationProfile = new CfnConfigurationProfile(
      this,
      "ConfigurationProfile",
      {
        name: "TestAppConfigProfile",
        applicationId: testAppConfigApp.ref,
        // we want AppConfig to manage the configuration profile, unless we need from SSM or S3.
        locationUri: "hosted",
        // This can also be "AWS.AppConfig.FeatureFlags"
        type: "AWS.Freeform",
      }
    );

    // Update AppConfig
    const configVersion: CfnHostedConfigurationVersion = new CfnHostedConfigurationVersion(
      this,
      "HostedConfigurationVersion",
      {
        applicationId: testAppConfigApp.ref,
        configurationProfileId: appConfigProfile.ref,
        content: JSON.stringify({
          someAppConfigResource: "SomeAppConfigResourceValue",
          //... add more as needed.
        }),
        // https://www.rfc-editor.org/rfc/rfc9110.html#name-content-type
        contentType: "application/json",
      }
    );

    // Perform deployment.
    new CfnDeployment(this, "Deployment", {
      applicationId: testAppConfigApp.ref,
      configurationProfileId: appConfigProfile.ref,
      configurationVersion: configVersion.ref,
      deploymentStrategyId: immediateDeploymentStrategy.ref,
      environmentId: appConfigEnv.ref,
    });
  }
}

Here is what goes inside my lambda handler (please note that you should have lambda layers enabled for AppConfig extension, see more information here):

const http = require('http');

exports.handler = async (event) => {
  
  const res = await new Promise((resolve, reject) => {
    http.get(
      "http://localhost:2772/applications/TestAppConfigApp/environments/Production/configurations/TestAppConfigProfile", 
      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));
  });
  const parsedConfigData = JSON.parse(configData);    
  return parsedConfigData;
};

EDIT: As promised, I released a new npm library : https://www.npmjs.com/package/cdk-appconfig, as of this update, this is still pre-release, but time permitting I will release a 1.x soon. But this will allow people to check out/fork if need be. Please share feedback/or open PRs if you'd like to collaborate.