![](/img/trans.png)
[英]ERROR aws_cloudwatch_log_subscription_filter to AWS Lambda with Terraform
[英]Terraform: configuring cloudwatch log subscription delivery to lambda?
我需要將我的 cloudwatch 日志發送到日志分析服務。
我一直在關注這些文章here和here並手動完成它,不用擔心。
現在我正在嘗試使用 Terraform(角色/策略、安全組、cloudwatch 日志組、lambda 和從日志組觸發 lambda)來自動化所有這些。
但我不知道如何使用 TF 來配置 AWS 以從 cloudwatch 日志中觸發 lambda。
我可以通過執行以下操作(在 Lambda Web 控制台 UI 中)手動將兩個 TF 資源鏈接在一起:
完成后,lambda 將顯示在 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:供應商 lambda 的 destinationArn 不能與 roleArn 一起使用
我找到了這個關於為計划事件設置類似事物的答案,但這似乎並不等同於我上面描述的控制台操作所做的事情(控制台 UI 方法不會創建我可以看到的事件/規則)。
有人可以告訴我我做錯了什么嗎?
我錯誤地定義了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->lambda
觸發器的相關資源):
// 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}"
}
編輯:請注意,上面的 TF 代碼是多年前編寫的,使用版本0.11.x
- 它應該仍然有效,但可能有更好的做事方法。 具體來說,除非需要,否則不要使用這樣的內聯策略,而是使用aws_iam_policy_document - 隨着時間的推移,它們更容易維護。
使用 Terraform v0.12.29
和 AWS provider v3.1.0
我遇到了一個奇怪的問題,這花了我幾個小時的調試時間。
為了節省其他人一些寶貴的時間,我將分享它作為對已接受答案的補充。
cloudwatch 日志組 arn 的值:
${aws_cloudwatch_log_group.test-app-loggroup.arn}
未正確插入- 輸出末尾缺少“ :*
”。
這導致以下錯誤:
創建 {the-calling-service} 時出錯:InvalidCloudWatchLogsLogGroupArnException:檢查日志組 ARN:{the-calling-service} 無法驗證。
添加:*
后綴解決了該問題:
source_arn = "${aws_cloudwatch_log_group.test-app-loggroup.arn}:*" #<----Notice the :* postfix
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.