The task is an Azure Function App that runs as a Timer Trigger that retrieves all AWS secrets with a specific Tag, then list those secrets. The code works,
- I can retrieve SecretId with a specific tag, but I want it to get the secret values.
- I can get the secret value if I hard code the SecretId.
I believe it is a nested asynch function issue.
module.exports = async function awsconnect(context, accessKey, accessSecret) { // Load the AWS SDK var AWS = require('aws-sdk'), params = { Filters: [ { Key: "tag-key", Values: [ 'AZ_PIPELINE', ] }, ] }; AWS.config.update({ accessKeyId: accessKey, secretAccessKey: accessSecret, region: "ap-southeast-2", }); // Create a Secrets Manager client var client = new AWS.SecretsManager(); let listSecret = await listAwsSecrets(context, client, params) } async function listAwsSecrets(context, client, params) { return new Promise(function (resolve, reject) { client.listSecrets(params, (err, data) => { if (err) { context.log('Error getting credentials', err); return reject(err); } else { data.SecretList.forEach(function (item) { const secret = client.getSecretValue({ SecretId: item.Name }).promise(); context.debug('Id=', item.Name, secret); }); return resolve(); } }); }); }
If I run the above code in Kudu. I get the following
AWSConnect timer trigger function ran! 2022-03-08T04:27:09.048Z Id= S3_SIT Promise { <pending> } Id= App-SIT-V2 Promise { <pending> } Id= APP-JOHN_DOE-V2 Promise { <pending> }
The three Secret_Ids above has the matching tag. The “pending” indicates a synch issue. But if I put await in front as per
const secret = await client.getSecretValue({ SecretId: item.Name }).promise();
It tells me that await is only valid in async function, I also get this error if I wrap this line in a async function.
So stepping back, how do I call listSecrets that matches a specific tag and get the secret value for each secretId?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Can you try by changing the following lines of code:
data.SecretList.forEach(function (item) { const secret = client.getSecretValue({ SecretId: item.Name }).promise(); context.debug('Id=', item.Name, secret); });
to
data.SecretList.forEach(async function (item) { const secret = await client.getSecretValue({ SecretId: item.Name }); context.debug('Id=', item.Name, secret); });
or
for (let i=0; i<data.SecretList.length; i++) { const item = data.SecretList[i]; const secret = await client.getSecretValue({ SecretId: item.Name }); context.debug('Id=', item.Name, secret); }
Method 2
Ok, I got the code to work as follows: Use the .then.catch to list the SecretIds and then await/promise to get the secrets for each Id.
listAwsSecrets(client, params).then(function (data) { data.SecretList.forEach(async (item) => { const secret = await client.getSecretValue({ SecretId: item.Name }).promise(); console.log('Id=', item.Name, secret); }); }).catch(err=> { console.log("Error listing secrets", err); }) } function listAwsSecrets(client, params) { return new Promise(function (resolve, reject) { client.listSecrets(params, (err, data) => { if (err) { return reject(err); } else { resolve(data); } }); }); }
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0