Terraform múltiplos eventos de cloudwatch accionam a mesma função lambda

Preparei o seguinte em Terraform. Então, duas regras de eventos, iniciar às 8 da manhã e parar às 6 da tarde.

# Create cloudwatch event rules
resource "aws_cloudwatch_event_rule" "stop_ec2_event_rule" {
  name        = "stop-ec2-event-rule"
  description = "Stop EC2 instance at a specified time each day"
  schedule_expression = var.cloudwatch_schedule_stop
}

resource "aws_cloudwatch_event_rule" "start_ec2_event_rule" {
  name        = "start-ec2-event-rule"
  description = "Start EC2 instance at a specified time each day"
  schedule_expression = var.cloudwatch_schedule_start
}
Cada evento passa uma acção para o lambda.
resource "aws_cloudwatch_event_target" "stop_ec2_event_rule_target" {
  rule      = aws_cloudwatch_event_rule.stop_ec2_event_rule.name
  target_id = "TriggerLambdaFunction"
  arn       = aws_lambda_function.lambda_rscheduler.arn
  input     = "{\"environment\":\"${var.environment}\", \"action\":\"stop\"}"
}

resource "aws_cloudwatch_event_target" "start_ec2_event_rule_target" {
  rule      = aws_cloudwatch_event_rule.start_ec2_event_rule.name
  target_id = "TriggerLambdaFunction"
  arn       = aws_lambda_function.lambda_rscheduler.arn
  input     = "{\"environment\":\"${var.environment}\", \"action\":\"start\"}"
}

isto funciona


resource "aws_lambda_permission" "allow_cloudwatch" {
  statement_id  = "AllowExecutionFromCloudWatch"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.lambda_rscheduler.function_name
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.stop_ec2_event_rule.arn
Este problema que estou a enfrentar é que não consigo que a Terraform associe o start_event à função lambda. Vou à consola AWS e posso adicionar manualmente o gatilho CloudWatch start_event à função lambda.

Se eu tiver o início. recursos

resource "aws_lambda_permission" "allow_cloudwatch" {
  statement_id  = "AllowExecutionFromCloudWatch"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.lambda_rscheduler.function_name
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.start_ec2_event_rule.arn

ele vai reclamar que o statement_id é duplicado.

eu precisava de algo como a terraform aws_lambda_event_source_ mapping, mas isso só permite que as funções Lambda obtenham eventos de Kinesis, DynamoDB e SQS; e não um evento CloudWatch.

Como posso dizer à terraform para associar vários eventos de cloudwatch à mesma função lambda, Quando posso fazê-lo manualmente a partir da consola AWS?

Author: Marcin, 2020-12-10

1 answers

statement_id is not compulsory , so you can safety omit it from your {[[2]} and terraform will unique generate id for you automatically. Você também pode usar Contagem ou for_ each para guardar algum tipo de escrita para aws_lambda_permission.

Por exemplo, ao usar {[4] } pode definir aws_lambda_permission como sendo:

resource "aws_lambda_permission" "allow_cloudwatch" {
  
  for_each      = {for idx, v in [
      aws_cloudwatch_event_rule.stop_ec2_event_rule,
      aws_cloudwatch_event_rule.start_ec2_event_rule
  ]: idx => v}
  
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.lambda_rscheduler.function_name
  principal     = "events.amazonaws.com"
  source_arn    = each.value.arn
}

As versões analógicas podem ser escritas para aws_cloudwatch_event_rule e aws_cloudwatch_event_target de modo que o seu código seja baseado em for_each ou count sem as repetições de cópia e pasta.

 1
Author: Marcin, 2020-12-10 04:32:04