CloudFormation:将列表传递给 Lambda 函数
CloudFormation: Pass List to Lambda Function
我有一个 CloudFormation 脚本,可以为 RDS 备份创建一个 Lambda 函数。如何将服务器列表从 CloudFormation 模板传递到 lambda 函数?现在它们是硬编码的,我认为这并不理想。
CloudFormation 脚本:
{ "AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"ruleName": {
"Description": "Name for CloudWatch Rule.",
"Type": "String"
},
"cronSchedule": {
"Description": "Cron Schedule Expression",
"Type": "String",
"Default": "cron(0 05 * * ? *)"
},
"bucketName" : {
"Description": "S3 Bucket storing the lambda script",
"Type": "String"
},
"lambdaTimeout": {
"Description": "Timeout for Lambda",
"Type": "String",
"Default": "3"
},
"instanceList":{
"Description": "",
"Type": "String"
}
},
"Resources": {
"cloudWatchRule": {
"Type": "AWS::Events::Rule",
"DependsOn": "lambdaFunction",
"Properties": {
"Description": "Cron Schedule",
"Name": {
"Ref": "ruleName"
},
"ScheduleExpression": {
"Ref": "cronSchedule"
},
"State": "ENABLED",
"Targets": [
{
"Arn":{
"Fn::GetAtt": ["lambdaFunction","Arn"]
},
"Id": {
"Ref": "lambdaFunction"
}
}
]
}
},
"lambdaFunction": {
"Type":"AWS::Lambda::Function",
"DependsOn": [
"lambdaRdsBackupRole",
"rdsBackupExecutionPolicy"
],
"Properties":{
"Code": {
"S3Bucket": {
"Ref": "bucketName"
},
"S3Key": "lambdaFunctions/rdsBackup.zip"
},
"Role": {
"Fn::GetAtt": ["lambdaRdsBackupRole", "Arn"]
},
"Handler": "rdsBackup.lambda_handler",
"Environment":{
"Variables": {
"dbInstances": {
"Ref": "instanceList"
}
}
},
"Runtime": "python3.6",
"MemorySize": 128,
"Timeout": {
"Ref": "lambdaTimeout"
}
}
},
"lambdaRdsBackupRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/"
}
},
"rdsBackupExecutionPolicy": {
"DependsOn": [
"lambdaRdsBackupRole"
],
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "lambdaRdsBackupRolePolicy",
"Roles": [
{
"Ref": "lambdaRdsBackupRole"
}
],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"rds:AddTagsToResource",
"rds:DeleteDBSnapshot"
],
"Resource": "arn:aws:rds:*:*"
},
{
"Effect": "Allow",
"Action": [
"rds:ListTagsForResource",
"rds:CreateDBSnapshot"
],
"Resource": "arn:aws:rds:*:*"
},
{
"Effect": "Allow",
"Action": [
"rds:DescribeDBSnapshots"
],
"Resource": "*"
}
]
}
}
}
}
}
我添加了这个部分,但我不太确定它是否正确,如果是,我仍然不太确定从这里去哪里:
"Environment":{
"Variables": {
"dbInstances": {
"Ref": "instanceList"
}
}
},
Lambda 函数:
import boto3
import datetime
def lambda_handler(event, context):
print("Connecting to RDS")
client = boto3.client('rds')
# Instance to backup
dbInstances = ['testdb', 'testdb2']
for dbInstance in dbInstances:
print("RDS snapshot backups started at %s...\n" % datetime.datetime.now())
for snapshot in client.describe_db_snapshots(DBInstanceIdentifier=dbInstance, MaxRecords=50)['DBSnapshots']:
try:
createTs = snapshot['SnapshotCreateTime'].replace(tzinfo=None)
if createTs < datetime.datetime.now() - datetime.timedelta(days=30):
print("Deleting snapshot id:", snapshot['DBSnapshotIdentifier'])
client.delete_db_snapshot(
DBSnapshotIdentifier=snapshot['DBSnapshotIdentifier']
)
except Exception as e:
print("Error: "+ str(e))
pass
client.create_db_snapshot(
DBInstanceIdentifier=dbInstance,
DBSnapshotIdentifier=dbInstance+'{}'.format(datetime.datetime.now().strftime("%y-%m-%d-%H")),
Tags=[
{
'Key': 'Name',
'Value': 'dbInstance'
},
]
)
可能有几种方法可以做到这一点。下面列出了一些想到的。
1) 如果您准备将变量添加到云形成模板中,我会将 python 脚本内联添加到 cloudformation 模板中,您可以将数组作为变量传递到模板中。 http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html
2) 您可以为 lambda 函数创建一个环境变量,每次执行它时(无论是控制台还是命令行),您都可以使用新的数据库实例更新环境变量。 http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-environment
3) 您可以使用 API 网关之类的东西并将其绑定到 lambda 函数。您可以在 POST 请求中将数组传递给 lambda 函数。 http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html
在不知道您的最终目标的情况下,很难推荐其中之一。
我有一个 CloudFormation 脚本,可以为 RDS 备份创建一个 Lambda 函数。如何将服务器列表从 CloudFormation 模板传递到 lambda 函数?现在它们是硬编码的,我认为这并不理想。
CloudFormation 脚本:
{ "AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"ruleName": {
"Description": "Name for CloudWatch Rule.",
"Type": "String"
},
"cronSchedule": {
"Description": "Cron Schedule Expression",
"Type": "String",
"Default": "cron(0 05 * * ? *)"
},
"bucketName" : {
"Description": "S3 Bucket storing the lambda script",
"Type": "String"
},
"lambdaTimeout": {
"Description": "Timeout for Lambda",
"Type": "String",
"Default": "3"
},
"instanceList":{
"Description": "",
"Type": "String"
}
},
"Resources": {
"cloudWatchRule": {
"Type": "AWS::Events::Rule",
"DependsOn": "lambdaFunction",
"Properties": {
"Description": "Cron Schedule",
"Name": {
"Ref": "ruleName"
},
"ScheduleExpression": {
"Ref": "cronSchedule"
},
"State": "ENABLED",
"Targets": [
{
"Arn":{
"Fn::GetAtt": ["lambdaFunction","Arn"]
},
"Id": {
"Ref": "lambdaFunction"
}
}
]
}
},
"lambdaFunction": {
"Type":"AWS::Lambda::Function",
"DependsOn": [
"lambdaRdsBackupRole",
"rdsBackupExecutionPolicy"
],
"Properties":{
"Code": {
"S3Bucket": {
"Ref": "bucketName"
},
"S3Key": "lambdaFunctions/rdsBackup.zip"
},
"Role": {
"Fn::GetAtt": ["lambdaRdsBackupRole", "Arn"]
},
"Handler": "rdsBackup.lambda_handler",
"Environment":{
"Variables": {
"dbInstances": {
"Ref": "instanceList"
}
}
},
"Runtime": "python3.6",
"MemorySize": 128,
"Timeout": {
"Ref": "lambdaTimeout"
}
}
},
"lambdaRdsBackupRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/"
}
},
"rdsBackupExecutionPolicy": {
"DependsOn": [
"lambdaRdsBackupRole"
],
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "lambdaRdsBackupRolePolicy",
"Roles": [
{
"Ref": "lambdaRdsBackupRole"
}
],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"rds:AddTagsToResource",
"rds:DeleteDBSnapshot"
],
"Resource": "arn:aws:rds:*:*"
},
{
"Effect": "Allow",
"Action": [
"rds:ListTagsForResource",
"rds:CreateDBSnapshot"
],
"Resource": "arn:aws:rds:*:*"
},
{
"Effect": "Allow",
"Action": [
"rds:DescribeDBSnapshots"
],
"Resource": "*"
}
]
}
}
}
}
}
我添加了这个部分,但我不太确定它是否正确,如果是,我仍然不太确定从这里去哪里:
"Environment":{
"Variables": {
"dbInstances": {
"Ref": "instanceList"
}
}
},
Lambda 函数:
import boto3
import datetime
def lambda_handler(event, context):
print("Connecting to RDS")
client = boto3.client('rds')
# Instance to backup
dbInstances = ['testdb', 'testdb2']
for dbInstance in dbInstances:
print("RDS snapshot backups started at %s...\n" % datetime.datetime.now())
for snapshot in client.describe_db_snapshots(DBInstanceIdentifier=dbInstance, MaxRecords=50)['DBSnapshots']:
try:
createTs = snapshot['SnapshotCreateTime'].replace(tzinfo=None)
if createTs < datetime.datetime.now() - datetime.timedelta(days=30):
print("Deleting snapshot id:", snapshot['DBSnapshotIdentifier'])
client.delete_db_snapshot(
DBSnapshotIdentifier=snapshot['DBSnapshotIdentifier']
)
except Exception as e:
print("Error: "+ str(e))
pass
client.create_db_snapshot(
DBInstanceIdentifier=dbInstance,
DBSnapshotIdentifier=dbInstance+'{}'.format(datetime.datetime.now().strftime("%y-%m-%d-%H")),
Tags=[
{
'Key': 'Name',
'Value': 'dbInstance'
},
]
)
可能有几种方法可以做到这一点。下面列出了一些想到的。
1) 如果您准备将变量添加到云形成模板中,我会将 python 脚本内联添加到 cloudformation 模板中,您可以将数组作为变量传递到模板中。 http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html
2) 您可以为 lambda 函数创建一个环境变量,每次执行它时(无论是控制台还是命令行),您都可以使用新的数据库实例更新环境变量。 http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-environment
3) 您可以使用 API 网关之类的东西并将其绑定到 lambda 函数。您可以在 POST 请求中将数组传递给 lambda 函数。 http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html
在不知道您的最终目标的情况下,很难推荐其中之一。