Utilizing an AwsCustomResource in AWS CDK to access JSON values from a parameter store

I found a solution on Stack Overflow to access configurations stored in an AWS parameter. The implementation involves using the code snippet below:

export class SSMParameterReader extends AwsCustomResource {
  constructor(scope: Construct, name: string, props: SSMParameterReaderProps) {
    const { parameterName, region } = props;

    const ssmAwsSdkCall: AwsSdkCall = {
      service: 'SSM',
      action: 'getParameter',
      parameters: {
        Name: parameterName
      },
      region,
      physicalResourceId: {id:Date.now().toString()}
    };

    super(scope, name, { onUpdate: ssmAwsSdkCall,policy:{
        statements:[new iam.PolicyStatement({
        resources : ['*'],
        actions   : ['ssm:GetParameter'],
        effect:iam.Effect.ALLOW,
      }
      )]
   }});
  }

  public getParameterValue(): string {
    return this.getResponseField('Parameter.Value').toString();
  }
}

However, I encountered a JSON parameter and struggled to access its value. One example is

{ "subnetId": "subnet-xxxxxx" }
.

I attempted modifying the code to extract the value with no success, such as:


  ...

  public getParameterValue(path: string): string {
    return this.getResponseField(`Parameter.Value.${path}`).toString();
  }

If you have any insight on how to extract the value of the parameter like subnetId, please share your knowledge.

Answer №1

By utilizing a lambda-backed custom resource (CR), you have the ability to retrieve the parameter and parse the JSON string directly within the custom resource handler itself. This solution has been designed to accommodate optional cross-region parameters and allows for any number of keys within the stringified parameter.

Step 1: Crafting a custom resource

To streamline the process, I have wrapped the custom resource, provider, and lambda handler within a construct wrapper for convenience. Simply pass the SSM parameter name and an optional region as props, with the stack's default region being utilized if no specific region is provided.

// GetJsonParamCR.ts

export interface GetJsonParamCRProps {
  parameterName: string;
  region?: string;
}

// Rest of the code remains the same...

Step 2: Defining the CR lambda handler

The Lambda function begins by fetching the parameter using the JS SDK v3, preloaded with 18.x Lambdas. Subsequently, it parses the parameter string to extract key-value pairs. Error handling has been omitted for simplicity.

// index.ts

// Lambda handler code remains unchanged...

Step 3: Integrating the CR into a stack

Incorporate the custom resource within a stack, showcasing how to consume the value using CfnOutput. Upon deployment, the output value will be displayed in the console for easy access.

This solution caters to JSON parameters with multiple keys, enabling convenient access using methods such as

r.customResource.getAttString("anotherKey")
.

// MyStack.ts

// Stack integration code remains the same...

Alternative Approach: No Custom Resource, Limited Cross-Region Support

If the strict requirement for a custom resource and cross-region support can be relaxed, a more straightforward solution emerges. Leveraging the StringParameter.valueFromLookup method eliminates the need for complex custom resources. This context method performs the necessary SDK call at synth-time, providing cached results for direct parsing within your CDK code.

Similarly, a CfnOutput value has been included to showcase the simplicity of retrieving the desired value.

export class NoCustomResourceStack extends cdk.Stack {

// Integration without custom resource code remains the same...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Understanding the concept of mutable properties in Typescript

Why can the property 'name' in the class 'PersonImpl' be reassigned even though it is not declared as read-only in the Person interface? interface Person { readonly name: string; } interface Greeting extends Person { greet( ...

The property "state" of RouteComponentProps location does not exist in the provided type {}

We recently encountered a new error that was not present before. Previously, our code compiled without any issues and the compilation process went smoothly. However, individuals who installed the react application from scratch are now facing an error speci ...

What specific event do I require for the onChange event in React using TypeScript?

I'm facing a problem while working with React TypeScript. I need to type the onChange event for a select element, but the data is coming from event.value instead of event.target.value. What should be the appropriate event to use in this case? Below i ...

Using Stack and Drawer Navigations Together in React Native Navigation(v6)

I am looking to merge Stack and Drawer navigations. I have multiple screens and wish to display select screen labels in the drawer tab. <RootNavigatorStack.Navigator> <RootNavigatorStack.Screen name="DrawerTab" component={DrawerNavig ...

Exploring the power of Next.js, Styled-components, and leveraging Yandex Metrica Session Replay

I'm currently involved in a project that utilizes Next.js and styled-components. In my [slug].tsx file: export default function ProductDetails({ product }: IProductDetailsProps) { const router = useRouter(); if (router.isFallback) { return ( ...

Convert the date into a string format instead of a UTC string representation

I am currently working on a node.js project using TypeScript. In this project, I have a Slot class defined as follows: export class Slot { startTime: Date; constructor(_startTime: Date){ this.startTime = _startTime } } // Within a controller method ...

It is not always a guarantee that all promises in typescript will be resolved completely

I have a requirement in my code to update the model data { "customerCode": "CUS15168", "customerName": "Adam Jenie", "customerType": "Cash", "printPackingSlip": "true", "contacts": [ { "firstName": "Hunt", "lastName": "Barlow", ...

Is there a way to deactivate the click function in ngx-quill editor for angular when it is empty?

In the following ngx-quill editor, users can input text that will be displayed when a click button is pressed. However, there is an issue I am currently facing: I am able to click the button even if no text has been entered, and this behavior continues li ...

Typescript Next.js Project with Custom Link Button Type Definition

I have a project that includes a custom Button component and a NextLink wrapper. I want to merge these two components for organization purposes, but when I combine the props for each, I encounter an issue with spreading the rest in the prop destructuring s ...

In Typescript, a function that is declared with a type other than 'void' or 'any' is required to have a return value

I'm a beginner in Angular2/Typescript and I am encountering an error while trying to compile my project: An error is showing: A function that has a declared type other than 'void' or 'any' must return a value. Here is the code sn ...

Tips for incorporating a mail button to share html content within an Angular framework

We are in the process of developing a unique Angular application and have integrated the share-buttons component for users to easily share their referral codes. However, we have encountered an issue with the email button not being able to send HTML content ...

Tips on extracting value from a pending promise in a mongoose model when using model.findOne()

I am facing an issue: I am unable to resolve a promise when needed. The queries are executed correctly with this code snippet. I am using NestJs for this project and need it to return a user object. Here is what I have tried so far: private async findUserB ...

Inferring types from synchronous versus asynchronous parameters

My objective is to create an "execute" method that can deliver either a synchronous or an asynchronous result based on certain conditions: type Callback = (...args: Arguments) => Result const result: Result = execute(callback: Callback, args: Arguments) ...

Issue detected in rxjs-compat operator's shareReplay file at line 2, column 10:

I've encountered an issue with the angular material spinner I'm using in my project. The error message is as follows: ERROR in node_modules/rxjs-compat/operator/shareReplay.d.ts(2,10): error TS2305: Module '"D:/ControlCenter/ofservices ...

Is there a way to retrieve a compilation of custom directives that have been implemented on the Vue 3 component?

Is there a way to retrieve the list of custom directives applied to a component? When using the getCurrentInstance method, the directives property is null for the current component. I was expecting to see 'highlight' listed. How can I access the ...

Customize the color of a specific day in the MUI DatePicker

Has anyone successfully added events to the MUI DatePicker? Or does anyone know how to change the background color of a selected day, maybe even add a birthday event to the selected day? https://i.stack.imgur.com/or5mhm.png https://i.stack.imgur.com/so6Bu ...

Tips for guaranteeing the shortest possible period of operation

I am in the process of constructing a dynamic Angular Material mat-tree using data that is generated dynamically (similar to the example provided here). Once a user expands a node, a progress bar appears while the list of child nodes is fetched from the ...

Issues with type errors in authentication wrapper for getServerSideProps

While working on implementing an auth wrapper for getServerSideProps in Next.js, I encountered some type errors within the hook and on the pages that require it. Below is the code for the wrapper along with the TypeScript error messages. It's importan ...

When faced with the error message "Typescript property does not exist on union type" it becomes difficult to assess the variable

This question is a continuation of the previous discussion on Typescript property does not exist on union type. One solution suggested was to utilize the in operator to evaluate objects within the union. Here's an example: type Obj1 = { message: stri ...

Is jest the ideal tool for testing an Angular Library?

I am currently testing an Angular 9 library using Jest. I have added the necessary dependencies for Jest and Typescript in my local library's package.json as shown below: "devDependencies": { "@types/jest": "^25.1.3", "jest": "^25.1.0", ...