2016-07-16 76 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

感謝您的支持! –