使用带有加密密钥 (KMS) 和环境变量的 lambda 函数从 RDS 访问表数据
第 1 步:-首先在 KMS(密钥管理服务 (KMS))中启用密钥
查看您的关键政策并完成!通过 KMS 创建
{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::163806924483:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::163806924483:user/User1@gmail.com"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::163806924483:user/User1@gmail.com",
"arn:aws:iam::163806924483:user/User2@gmail.com",
"arn:aws:iam::163806924483:user/User3@gmail.com"
]
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::163806924483:user/User1.dilip@gmail.com",
"arn:aws:iam::163806924483:user/User2@gmail.com",
"arn:aws:iam::163806924483:user/User3@gmail.com"
]
},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}
步骤:- 2在 IAM 中为 KMS 创建一个策略,将其分配给您的每个 lambda 函数
"StringEquals": {
"kms:EncryptionContext:LambdaFunctionName": [
"LambdaFunction-1",
"LambdaFunction-2",
"LambdaFunction-3"
]
}
第 3 步:-将在第 2 步中创建的策略分配给您的默认 lambda 角色(需要创建第一个 Lambda 以获得默认 lambda 角色)
第 4 步:- 创建 lambda 函数
lambda 函数的Node.js代码
const mysql = require('mysql');
const aws = require("aws-sdk");
const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
let res;
let response={};
exports.handler = async(event) => {
reset_globals();
// load env variables
const rds_user = await kms_decrypt(process.env.RDS_USERNAME);
const rds_pwd = await kms_decrypt(process.env.RDS_PASSWORD)
// setup rds connection
var db_connection = await mysql.createConnection({
host: process.env.RDS_HOSTNAME,
user: rds_user,
password: rds_pwd,
port: process.env.RDS_PORT,
database: process.env.RDS_DATABASE
});
var sqlQuery = `SELECT doc_id from documents`;
await getValues(db_connection,sqlQuery);
}
async function getValues(db_connection,sql) {
await new Promise((resolve, reject) => {
db_connection.query(sql, function (err, result) {
if (err) {
response = {statusCode: 500, body:{message:"Database Connection Failed",
error: err}};
console.log(response);
resolve();
}
else {
console.log("Number of records retrieved: " + JSON.stringify(result));
res = result;
resolve();
}
});
});
}
async function kms_decrypt(encrypted) {
const kms = new aws.KMS();
const req = { CiphertextBlob: Buffer.from(encrypted, 'base64'), EncryptionContext: {
LambdaFunctionName: functionName } };
const decrypted = await kms.decrypt(req).promise();
let cred = decrypted.Plaintext.toString('ascii');
return cred;
}
function reset_globals() {
res = (function () { return; })();
response = {};
}
现在你应该在 Lambda 中看到 KMS。
第 5 步:-设置环境变量并加密。
Lambda -> 函数 -> 配置 -> 环境变量 -> 编辑
RDS_DATABASE 文档
RDS_HOSTNAME docrds-library.c1k3kcldebmp.us-east-1.rds.amazonaws.com
RDS_PASSWORD root123
RDS_PORT 3306
RDS_USERNAME 管理员
在 Lambda 函数中解密加密的环境变量,使用下面的代码
function kms_decrypt(encrypted) {
const kms = new aws.KMS();
const req = { CiphertextBlob: Buffer.from(encrypted, 'base64'), EncryptionContext: {
LambdaFunctionName: functionName } };
const decrypted = await kms.decrypt(req).promise();
let cred = decrypted.Plaintext.toString('ascii');
return cred;
}
我的 RDS 文档表如下所示:-
我在 lambda 函数中使用 sqlQuery 访问列 doc_id
var sqlQuery = `SELECT doc_id from documents`;
测试 lambda 函数后,我得到以下输出。
如果你得到 SQL 导入错误,那么必须添加一个层。
errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module 'mysql'\nRequire stack:\n-
/var/task/index.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js",
"trace": [
"Runtime.ImportModuleError: Error: Cannot find module 'mysql'",
您可以配置您的 Lambda 函数以使用层形式的其他代码和内容。层是包含库、自定义运行时或其他依赖项的 ZIP 存档。通过层,您可以在函数中使用库,而无需将它们包含在部署包中。
要将库包含在层中,请将它们放在与您的编程语言对应的目录结构中。
Node.js – nodejs/node_modules
蟒蛇——蟒蛇
红宝石 - 红宝石/宝石/2.5.0
Java – java/lib
首先创建一个包含 mysql 归档的 zip 归档。
首先创建一个反应项目
然后在终端 $project-path > npm init
然后 $project-path > npm install mysql
您应该会看到创建的 node_modules 文件夹。
压缩 node_modules 该文件夹并上传到图层,如下所示。
然后,转到 Lambda--> 层--> 创建层。