【问题标题】:AWS Lambda function with placeholders带有占位符的 AWS Lambda 函数
【发布时间】:2021-04-14 08:54:29
【问题描述】:

我正在为我的 python 函数开发 AWS Lambda 函数。我有一个 python 函数,它从文件中调用 IAM 策略并使用该函数填充它。这是我的函数,文件名是 template_utils.py":

import sys
import json
import time 
import meta_templates
from jinja2 import Template
def lambda_handler(event,context):
  template_data = {}
  template_data["region"] = event.get('region')
  template_data["instance_types"] = event.get('instance_type')
  template_data["ebs_volume_size"] = event.get('ebs_volume_size')
  template_data["meta_template_name"] = event.get('meta_template_name')

  meta_template_dict = getattr(meta_templates, template_data["meta_template_name"])
  meta_template_json = json.dumps(meta_template_dict)
  template_json = Template(meta_template_json).render(template_data)
  return template_json  

template_json = lambda_handler(
  region="us-east-2",
  instance_type="t2.micro",
  ebs_volume_size="20",
  meta_template_name="ec2_policy_meta_template"
)

print(template_json)

这是我的名为“meta_templates.py”的策略文件

import json
from jinja2 import Template
ec2_policy_meta_template = { 
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": "ec2:RunInstances",
                "Resource": [
                    "arn:aws:ec2:{{region}}::instance/*",
                    "arn:aws:ec2:{{region}}::network-interface/*",
                    "arn:aws:ec2:{{region}}::key-pair/*",
                    "arn:aws:ec2:{{region}}::security-group/*",
                    "arn:aws:ec2:{{region}}::subnet/*",
                    "arn:aws:ec2:{{region}}::volume/*",
                    "arn:aws:ec2:{{region}}::image/ami-*"
                ],
                "Condition": {
                    "ForAllValues:NumericLessThanEquals": {
                        "ec2:VolumeSize": "{{ebs_volume_size}}"
                    },
                    "ForAllValues:StringEquals": {
                        "ec2:InstanceType": "{{instance_type}}"
                    }
                }
            },
            {
                "Sid": "VisualEditor1",
                "Effect": "Allow",
                "Action": [
                    "ec2:TerminateInstances",
                    "ec2:StartInstances",
                    "ec2:StopInstances"
                ],
                "Resource": "arn:aws:ec2:{{region}}::instance/*",
                "Condition": {
                    "ForAllValues:StringEquals": {
                        "ec2:InstanceType": "{{instance_type}}"
                    }
                }
            },
            {
                "Sid": "VisualEditor2",
                "Effect": "Allow",
                "Action": [
                    "ec2:Describe*",
                    "ec2:GetConsole*",
                    "cloudwatch:DescribeAlarms",
                    "iam:ListInstanceProfiles",
                    "cloudwatch:GetMetricStatistics",
                    "ec2:DescribeKeyPairs",
                    "ec2:CreateKeyPair"
                ],
                "Resource": "*",
                "Condition": {
                    "DateGreaterThan": {
                        "aws:CurrentTime": "{{start_time}}"
                    },
                    "DateLessThanEquals": {
                        "aws:CurrentTime": "{{end_time}}"
                    }
                }
            }
        ]
    }

我想创建一个与函数“template_utils.py”执行相同操作的 lambda 处理程序。我是新手,不知道如何继续。我收到此错误:

Traceback (most recent call last):
  File "/home/pranay/Desktop/work/lambda_handler.py", line 18, in <module>
    template_json = lambda_handler(
TypeError: lambda_handler() got an unexpected keyword argument 'region'

【问题讨论】:

  • lambda_handler 需要一个事件和上下文,你给它一个区域 - 这显然不会起作用。
  • 删除了所有与 AWS 相关的标签,因为这不是 AWS 特定的,而是一个常规的 python 问题?
  • 这是一个 aws-lambda 函数,因此我将使用它来调用 AWS 上的函数,因此我认为包含这些标签可能会提供更好的外展服务

标签: python python-3.x amazon-web-services aws-lambda boto3


【解决方案1】:

这应该可以工作,前提是您在事件中传递了正确的数据。

import json


def lambda_handler(event, context):
    template_data = {}
    region = event.get('region')
    instance_type = event.get('instance_type')
    ebs_volume_size = event.get('ebs_volume_size')
    start_time = event.get('start_time')
    end_time = event.get('end_time')

    ec2_policy_meta_template = { 
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Sid": "VisualEditor0",
                  "Effect": "Allow",
                  "Action": "ec2:RunInstances",
                  "Resource": [
                      "arn:aws:ec2:{{region}}::instance/*",
                      "arn:aws:ec2:{{region}}::network-interface/*",
                      "arn:aws:ec2:{{region}}::key-pair/*",
                      "arn:aws:ec2:{{region}}::security-group/*",
                      "arn:aws:ec2:{{region}}::subnet/*",
                      "arn:aws:ec2:{{region}}::volume/*",
                      "arn:aws:ec2:{{region}}::image/ami-*"
                  ],
                  "Condition": {
                      "ForAllValues:NumericLessThanEquals": {
                          "ec2:VolumeSize": "{{ebs_volume_size}}"
                      },
                      "ForAllValues:StringEquals": {
                          "ec2:InstanceType": "{{instance_type}}"
                      }
                  }
              },
              {
                  "Sid": "VisualEditor1",
                  "Effect": "Allow",
                  "Action": [
                      "ec2:TerminateInstances",
                      "ec2:StartInstances",
                      "ec2:StopInstances"
                  ],
                  "Resource": "arn:aws:ec2:{{region}}::instance/*",
                  "Condition": {
                      "ForAllValues:StringEquals": {
                          "ec2:InstanceType": "{{instance_type}}"
                      }
                  }
              },
              {
                  "Sid": "VisualEditor2",
                  "Effect": "Allow",
                  "Action": [
                      "ec2:Describe*",
                      "ec2:GetConsole*",
                      "cloudwatch:DescribeAlarms",
                      "iam:ListInstanceProfiles",
                      "cloudwatch:GetMetricStatistics",
                      "ec2:DescribeKeyPairs",
                      "ec2:CreateKeyPair"
                  ],
                  "Resource": "*",
                  "Condition": {
                      "DateGreaterThan": {
                          "aws:CurrentTime": "{{start_time}}"
                      },
                      "DateLessThanEquals": {
                          "aws:CurrentTime": "{{end_time}}"
                      }
                  }
              }
          ]
      }
      
    json_data = json.dumps(ec2_policy_meta_template)

    # Update resources with a string replacement
    json_data = json_data.replace("{{region}}", region)
    json_data = json_data.replace("{{instance_type}}", instance_type)
    json_data = json_data.replace("{{ebs_volume_size}}", ebs_volume_size)
    json_data = json_data.replace("{{start_time}}", start_time)
    json_data = json_data.replace("{{end_time}}", end_time)
    
    return json_data

此示例仅使用 Python(没有第三方库),它不是最优雅的解决方案,但它很简单。如果您想创建额外的替换,只需添加一些额外的标签“{{some_text}}”并替换它,如下所示。

这是一个在 lambda 控制台上运行的测试事件。

这是一个有效调用的示例

【讨论】:

  • 该应用程序是基于 python 的,因此我们需要使用 Boto,我对 python 很陌生,所以我需要一些时间来理解,你的程序运行良好,但这并没有给出输出json 格式我应该在这里打印什么。TIA。
  • 另外,region、instance_type 和 ebs_volume 的值需要在函数中。我无法摆脱那部分。
  • 你打算用 boto 做什么?您提出的问题没有与 boto 相关的要求,您只是通过事件向模板提供值来解析模板。一个 lambda 处理程序只能接受两个参数,您无法更改 docs.aws.amazon.com/lambda/latest/dg/python-handler.html。即使可以,该服务也只会向其传递两个参数。这两个参数本质上是两个字典,您可以在其中使用 event.get('region') 等访问值。
  • 我的查询与 boto 无关我只是在解释为什么我不使用 terraform,我只是不确定如何从 lambda 函数填充模板中的占位符。
  • 好的,不用担心,您尝试做的事情相对简单,但使用 lambda 完成此任务的学习曲线更陡峭。对于初学者来说,Jinja2 库不包含在 lambda 环境中,因此如果您想使用 lambda,您需要学习如何打包和压缩 3rd 方库。如果您想要一个简单的解决方案,我可以调整我之前的答案以使用 f-strings,这将允许您在函数内创建模板,参数将来自事件(区域、instance_types 等)。
猜你喜欢
  • 2020-07-04
  • 2018-10-15
  • 1970-01-01
  • 2022-01-22
  • 2014-12-25
  • 1970-01-01
  • 2011-07-26
  • 1970-01-01
  • 2018-10-21
相关资源
最近更新 更多