2016-07-16 112 views
12

Devo spedire i miei registri di cloudwatch a un servizio di analisi dei registri.Terraform: configurazione della consegna dell'abbonamento del log di cloudwatch a lambda?

Ho seguito insieme a questi articoli here e here e ho funzionato a mano, senza preoccupazioni.

Ora sto cercando di automatizzare tutto questo con Terraform (ruoli/criteri, gruppi di sicurezza, gruppo di log di cloudwatch, lambda e attivazione del lambda dal gruppo di log).

Ma non riesco a capire come utilizzare TF per configurare AWS per avviare il lambda dai registri di cloudwatch.

posso collegare le due risorse TF insieme a mano nel modo seguente (nella Lambda console Web UI):

  • andare in sezione "trigger" della funzione lambda
  • clic su "Aggiungi trigger"
  • selezionare "i log CloudWatch" dall'elenco dei tipi di trigger
  • selezionare il gruppo di registro voglio innescare la lambda
  • immettere un nome di filtro
  • lasciare il disegno filtro vuoto (trigger che implica su tutti i flussi di log)
  • assicurarsi "abilitazione grilletto" è selezionato
  • clic

il pulsante di invio Una volta fatto, il lambda si presenta sui tronchi CloudWatch console nella colonna delle iscrizioni - viene visualizzato come "Lambda (cloudwatch-sumologic-lambda)".

ho cercato di creare l'abbonamento con la seguente risorsa 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}" 
} 

ma non riesce con:

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

ho trovato this answer sull'impostazione di una cosa simile per un evento programmato, ma ciò non sembra essere equivalente a ciò che le azioni della console ho descritto sopra (il metodo UI della console non crea un evento/regola che posso vedere).

Qualcuno può darmi un puntatore su cosa sto facendo male, per favore?

+0

E 'difficile vedere esattamente, ma sembra che AWS sta dicendo che il ruolo che hai assegnato a PutSubscriptionFilter non ha accesso a Lambda. Puoi anche pubblicare la definizione della risorsa 'aws_iam_role.jordi-waf-cloudwatch-lambda-role.arn'? – ydaetskcoR

risposta

18

Ho avuto la risorsa "aws_cloudwatch_log_subscription_filter" definita in modo errato - non si dovrebbe fornire l'argomento "role_arn" in questa situazione.

È inoltre necessario aggiungere una risorsa aws_lambda_permission (con una relazione "depends_on" definita sul filtro o TF potrebbe farlo nell'ordine errato).

Nota che l'interfaccia utente della console lambda di AWS aggiunge l'autorizzazione lambda per te in modo invisibile, quindi fai attenzione che "aws_cloudwatch_log_subscription_filter" funzionerà senza la risorsa di autorizzazione se hai già eseguito la stessa azione nell'interfaccia della console.

La configurazione necessaria TF si presenta così (gli ultimi due risorse sono quelle rilevanti per la configurazione del cloudwatch- reale> lambda trigger):

// 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

Grazie per questo! –