简体   繁体   English

在 AWS Lambda@Edge 中使用 SecretManager

[英]Utilizing SecretManager in AWS Lambda@Edge

I want to get a secret in my aws L@E function, and in the code I must set a region to my SecretManager instance我想在我的 aws L@E function 中获取一个秘密,并且在代码中我必须为我的 SecretManager 实例设置一个区域

// Create a Secrets Manager client
const client = new AWS.SecretsManager({
    region: "us-east-1", // mandatory param
});

but I know that SecretManager also has multi-region support so i don't understand how it work together with the L@E function. how can I know on runtime what is the best region to use?但我知道 SecretManager 也有多区域支持,所以我不明白它是如何与 L@E function 一起工作的。我如何在运行时知道哪个区域是最好使用的? and also what happens if there is a downtime in one region?还有,如果一个地区发生停机怎么办? in addition to caching the secrets via lambda global variables, is it possible also to optimize the SecretManager usage?除了通过 lambda 全局变量缓存秘密外,是否还可以优化 SecretManager 的使用?

I tried using the process.env.AWS_REGION env variable, but its not supported我尝试使用process.env.AWS_REGION环境变量,但它不受支持

In case someone encounters this issue in the future, I got an answer from AWS support.万一以后有人遇到这个问题,我会从 AWS 支持部门得到答复。 There is no way to tell what is the "best" region to use on runtime via L@E.无法通过 L@E 判断在运行时使用的“最佳”区域是什么。 To protect against region downtime, the best practice is to try accessing a SecretManager instance from a primary region and have a fallback region (where it has been replicated) in case of an error.为了防止区域停机,最佳做法是尝试从主要区域访问 SecretManager 实例,并在出现错误时有一个回退区域(它已被复制)。

const AWS = require('aws-sdk');

const name = "app-api-key";
const primarySecretManager = new AWS.SecretsManager({
    region: 'us-east-1',
});
const fallbackSecretManager = new AWS.SecretsManager({
    region: "us-east-2",
});

const getSecrets = async () => {
    let secrets;
    try {
        secrets = await getSecretsInternal(primarySecretManager)
    } catch (e) {
        secrets = await getSecretsInternal(fallbackSecretManager)
    }
    return secrets
}

const getSecretsInternal = async client => {
    return new Promise((resolve, reject) => {
        client.getSecretValue({ SecretId: name }, (err, data) => {
            if (err) {
                switch (err.code) {
                    case 'DecryptionFailureException':
                        console.error(`Secrets Manager can't decrypt the protected secret text using the provided KMS key.`)
                        break
                    case 'InternalServiceErrorException':
                        console.error(`An error occurred on the server side.`)
                        break
                    case 'InvalidParameterException':
                        console.error(`You provided an invalid value for a parameter.`)
                        break
                    case 'InvalidRequestException':
                        console.error(`You provided a parameter value that is not valid for the current state of the resource.`)
                        break
                    case 'ResourceNotFoundException':
                        console.error(`We can't find the resource that you asked for.`)
                        break
                }
                console.error(err)
                reject(err)
                return
            }

            // Decrypts secret using the associated KMS CMK.
            // Depending on whether the secret is a string or binary, one of these fields will be populated.
            let secrets;
            if ('SecretString' in data) {
                secrets = data.SecretString;
            } else {
                const buff = new Buffer(data.SecretBinary, 'base64');
                secrets = buff.toString('ascii');
            }

            resolve(JSON.parse(secrets))
        })
    })
}

module.exports = {
    getSecrets,
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM