2016-07-16 103 views
12

我需要将我的CloudWatch日志发送到日志分析服务。Terraform:将cloudwatch日志预订配置配置到lambda?

我和这些文章herehere跟着一起,并得到它的手工工作,无后顾之忧。

现在我试图通过Terraform(角色/策略,安全组,cloudwatch日志组,lambda以及从日志组中触发lambda)自动执行所有这些操作。

但我无法弄清楚如何使用TF来配置AWS从cloudwatch日志中触发lambda。

我可以在这两个TF资源一起用手工通过执行以下(在lambda Web控制台UI)链接:

  • 进入lambda函数的“触发器”部分
  • 点击“添加触发器”
  • 从触发类型列表中选择“CloudWatch的日志”
  • 选择日志组我想要触发拉姆达
  • 输入过滤器名称
  • 离开(对所有日志流暗示触发)过滤模式空
  • 确保“启用触发器”时
  • 点击提交按钮

一旦这样做了,拉姆达显示了对CloudWatch的日志控制台 - 显示为“Lambda(cloudwatch-sumologic-lambda)”。

我试着用下面的TF资源创建订阅:

resource "aws_cloudwatch_log_subscription_filter" "cloudwatch-sumologic-lambda-subscription" { 
    name = "cloudwatch-sumologic-lambda-subscription" 
    role_arn = "${aws_iam_role.jordi-waf-cloudwatch-lambda-role.arn}" 
    log_group_name = "${aws_cloudwatch_log_group.jordi-waf-int-app-loggroup.name}" 
    filter_pattern = "logtype test" 
    destination_arn = "${aws_lambda_function.cloudwatch-sumologic-lambda.arn}" 
} 

但它失败:

* aws_cloudwatch_log_subscription_filter.cloudwatch-sumologic-lambda-subscription: InvalidParameterException: destinationArn for vendor lambda cannot be used with roleArn 

我发现this answer有关建立类似的事情,为计划事件,但这似乎并不等同于我上面描述的控制台操作(控制台UI方法不会创建我可以看到的事件/规则)。

有人可以给我一个指针,我在做什么错吗?

+0

很难清楚地看到,但它看起来像AWS是说,您赋予PutSubscriptionFilter的角色无法访问Lambda。你还可以发布'aws_iam_role.jordi-waf-cloudwatch-lambda-role.arn'资源的定义吗? – ydaetskcoR

回答

18

我有错误地定义了“aws_cloudwatch_log_subscription_filter”资源 - 在这种情况下,您不应该提供“role_arn”参数。

您还需要添加aws_lambda_permission资源(在过滤器上定义了“depends_on”关系或TF可能按错误顺序执行)。

请注意,AWS lambda控制台UI在不可见的情况下为您添加了lambda权限,因此,如果您恰好在控制台UI中完成了相同的操作,请注意,“aws_cloudwatch_log_subscription_filter”将在没有权限资源的情况下运行。

必要的TF的配置看起来像这样(最后两个资源是相关的多个配置的实际cloudwatch->拉姆达触发):

// intended for application logs (access logs, modsec, etc.) 
resource "aws_cloudwatch_log_group" "test-app-loggroup" { 
    name = "test-app" 
    retention_in_days = 90 
} 


resource "aws_security_group" "cloudwatch-sumologic-lambda-sg" { 
    name = "cloudwatch-sumologic-lambda-sg" 
    tags { 
    Name = "cloudwatch-sumologic-lambda-sg" 
    } 
    description = "Security group for lambda to move logs from CWL to SumoLogic" 
    vpc_id = "${aws_vpc.dev-vpc.id}" 
} 

resource "aws_security_group_rule" "https-egress-cloudwatch-sumologic-to-internet" { 
    type = "egress" 
    from_port = 443 
    to_port = 443 
    protocol = "tcp" 
    security_group_id = "${aws_security_group.cloudwatch-sumologic-lambda-sg.id}" 
    cidr_blocks = ["0.0.0.0/0"] 
} 

resource "aws_iam_role" "test-cloudwatch-lambda-role" { 
    name = "test-cloudwatch-lambda-role" 
    assume_role_policy = <<EOF 
{ 
    "Version": "2012-10-17", 
    "Statement": [ 
    { 
     "Action": "sts:AssumeRole", 
     "Principal": { 
     "Service": "lambda.amazonaws.com" 
     }, 
     "Effect": "Allow" 
    } 
    ] 
} 
EOF 
} 

resource "aws_iam_role_policy" "test-cloudwatch-lambda-policy" { 
    name = "test-cloudwatch-lambda-policy" 
    role = "${aws_iam_role.test-cloudwatch-lambda-role.id}" 
    policy = <<EOF 
{ 
    "Version": "2012-10-17", 
    "Statement": [ 
    { 
     "Sid": "CopiedFromTemplateAWSLambdaVPCAccessExecutionRole1", 
     "Effect": "Allow", 
     "Action": [ 
     "ec2:CreateNetworkInterface" 
     ], 
     "Resource": "*" 
    }, 
    { 
     "Sid": "CopiedFromTemplateAWSLambdaVPCAccessExecutionRole2", 
     "Effect": "Allow", 
     "Action": [ 
     "ec2:DescribeNetworkInterfaces", 
     "ec2:DeleteNetworkInterface" 
     ], 
     "Resource": "arn:aws:ec2:ap-southeast-2:${var.dev_vpc_account_id}:network-interface/*" 
    }, 

    { 
     "Sid": "CopiedFromTemplateAWSLambdaBasicExecutionRole1", 
     "Effect": "Allow", 
     "Action": "logs:CreateLogGroup", 
     "Resource": "arn:aws:logs:ap-southeast-2:${var.dev_vpc_account_id}:*" 
    }, 
    { 
     "Sid": "CopiedFromTemplateAWSLambdaBasicExecutionRole2", 
     "Effect": "Allow", 
     "Action": [ 
     "logs:CreateLogStream", 
     "logs:PutLogEvents" 
     ], 
     "Resource": [ 
    "arn:aws:logs:ap-southeast-2:${var.dev_vpc_account_id}:log-group:/aws/lambda/*" 
     ] 
    }, 

    { 
     "Sid": "CopiedFromTemplateAWSLambdaAMIExecutionRole", 
     "Effect": "Allow", 
     "Action": [ 
     "ec2:DescribeImages" 
     ], 
     "Resource": "*" 
    } 


    ] 
} 
EOF 
} 

resource "aws_lambda_function" "cloudwatch-sumologic-lambda" { 
    function_name = "cloudwatch-sumologic-lambda" 
    filename = "${var.lambda_dir}/cloudwatchSumologicLambda.zip" 
    source_code_hash = "${base64sha256(file("${var.lambda_dir}/cloudwatchSumologicLambda.zip"))}" 
    handler = "cloudwatchSumologic.handler" 

    role = "${aws_iam_role.test-cloudwatch-lambda-role.arn}" 
    memory_size = "128" 
    runtime = "nodejs4.3" 
    // set low because I'm concerned about cost-blowout in the case of mis-configuration 
    timeout = "15" 
    vpc_config = { 
    subnet_ids = ["${aws_subnet.dev-private-subnet.id}"] 
    security_group_ids = ["${aws_security_group.cloudwatch-sumologic-lambda-sg.id}"] 
    } 
} 

resource "aws_lambda_permission" "test-app-allow-cloudwatch" { 
    statement_id = "test-app-allow-cloudwatch" 
    action = "lambda:InvokeFunction" 
    function_name = "${aws_lambda_function.cloudwatch-sumologic-lambda.arn}" 
    principal = "logs.ap-southeast-2.amazonaws.com" 
    source_arn = "${aws_cloudwatch_log_group.test-app-loggroup.arn}" 
} 

resource "aws_cloudwatch_log_subscription_filter" "test-app-cloudwatch-sumologic-lambda-subscription" { 
    depends_on = ["aws_lambda_permission.test-app-allow-cloudwatch"] 
    name = "cloudwatch-sumologic-lambda-subscription" 
    log_group_name = "${aws_cloudwatch_log_group.test-app-loggroup.name}" 
    filter_pattern = "" 
    destination_arn = "${aws_lambda_function.cloudwatch-sumologic-lambda.arn}" 
} 
+0

感谢您的支持! –