2

I'm trying to programmatically upload a secret to an AWS Secret Manager instance using "@aws-sdk/client-secrets-manager": "^3.299.0", but I am continuously getting an error. I have followed the documentation here: https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-secrets-manager/classes/getsecretvaluecommand.html

I'm using Typescript version 5.0.2 and Node 18.x as runtime, and this is my tsconfig.json:

{
  "compilerOptions": {
    "module": "NodeNext",
    "target": "ESNext",
    "noImplicitAny": true,
    "preserveConstEnums": true,
    "outDir": "./dist",
    "sourceMap": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

and this is the code that is failing:


const client = new SecretsManagerClient({ region: 'my-region' });

async function getExistingSecret(connectionDetails: ConnectionDetails): Promise<string> {
  console.log('checking if secret exists');
  const command = getCommand(connectionDetails);
  console.log(`GetSecretValueCommand: ${JSON.stringify(command)}`);
  return client
    .send(command) // <----- FAILS HERE
    .catch(() => {
      console.log(`secret does not exist`);
      return null;
    })
    .then((response: GetSecretValueCommandOutput) => {
      console.log(`secret exists arn: ${response.ARN}`);
      return response.ARN;
    });
}


const getCommand = (connectionDetails: ConnectionDetails): GetSecretValueCommand => {
  const body = getCommandRequest(connectionDetails);
  console.log(`GetSecretValueRequest: ${JSON.stringify(body)}`);
  return { input: body } as GetSecretValueCommand;
};


const getCommandRequest = (connectionDetails: ConnectionDetails): GetSecretValueCommandInput => {
  return { SecretId: secretName(connectionDetails) } as GetSecretValueCommandInput;
};

The error that I get when I run this code is this:

TypeError: command.resolveMiddleware is not a function
    at SecretsManagerClient.send (/var/task/node_modules/@aws-sdk/smithy-client/dist-cjs/client.js:13:33)
    at getExistingSecret (/var/task/aws/secrets-client.js:35:10)
    at addSecret (/var/task/aws/secrets-client.js:8:12)
    at Runtime.handler (/var/task/index.js:9:29)
    at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1085:29)

I've checked these places along with the official docs mentioned above.

https://github.com/aws/aws-sdk-js-v3/issues/4456

command.resolveMiddleware is not a function for AWS SDK when creating AMI from EC2 instanceID, wondering why?

AWS Timestream - SDK V3 Nodejs, TimestreamWriteClient.send() - TypeError: command.resolveMiddleware is not a function. How to solve this?

Thanks in advance for any help!

Alex

I tried following documentation, and expected the code to not return this error.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
  • Did you tried using with await?no problem with await `import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager"; // ES Modules import // const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager"); // CommonJS import const client = new SecretsManagerClient(config); const input = { // GetSecretValueRequest SecretId: "STRING_VALUE", // required VersionId: "STRING_VALUE", VersionStage: "STRING_VALUE", }; const command = new GetSecretValueCommand(input); const response = await client.send(command);` – Jatin Mehrotra Mar 31 '23 at 00:20
  • so you mean putting `await` before `getExistingSecret(connectionDetails)`? – Alex Agathocleous Mar 31 '23 at 06:38
  • Posted a solution, hope it helps – Jatin Mehrotra Mar 31 '23 at 06:49

2 Answers2

1

Thanks so much for your input into this; I was tearing my hair out trying to work it out. It turns out that the GetSecretValueCommand should not be instantiated as:

const command = { Input: someInput } as GetSecretValueCommand

Instead one should use the provided constructor:

const command = new GetSecretValueCommand(someInput)

Only then is the object instantiated correctly.

Again, many thanks for your input on this!

Note for those who find this: It seems to me that this same "pattern" is uniform across all JavaScript V3 clients, so this should help even if you're working with Kinesis, S3 etc.

Alex

0

This is how I am using it with Typescript but it will also work with Javascript

function Definition

import { SecretsManagerClient, GetSecretValueCommand, GetSecretValueCommandOutput } from "@aws-sdk/client-secrets-manager";

async function ImportSecrets(secretId?: string): Promise<GetSecretValueCommandOutput> {

    const secretManagerClient = new SecretsManagerClient({ region: region });
    const secretManagerCommand = new GetSecretValueCommand({ SecretId: secretId });

    const secretManagerResponse = await secretManagerClient.send(secretManagerCommand);
    return secretManagerResponse  
}

function call

let secrets = await ImportSecrets('my-secret-name')

Note:- I am passing secret id name to the function. Ofcourse in my case I have creation secret manually.

Jatin Mehrotra
  • 9,286
  • 4
  • 28
  • 67