Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloudwatch Event trigger Lambda doesn't associate unless we do a manual update to cloudwatch event. #14342

Closed
s-nakka opened this issue May 10, 2017 · 16 comments

Comments

@s-nakka
Copy link

s-nakka commented May 10, 2017

Hi there,

Terraform Launches all the required resources as expected. But the Event trigger is not being associated with the lambda function. Had to update the cloudwatch event manually from the console to add it as a trigger to lambda and to invoke.

Terraform Version

Terraform v0.9.4

Affected Resource(s)

AWS Lambda
AWS Cloudwatch Event rule/target

Expected Behavior

Under lambda function triggers tab you should see the "CloudWatch Events - Schedule:*" and should be invoked by the Cloudwatch event as per the Schedule expression.

Actual Behavior

What actually happened?

Terraform Launches all the required resources as expected. But the Event trigger is not being associated with the lambda function. Had to update the cloudwatch event manually from the console to add it as a trigger to lambda and to invoke.

Steps to Reproduce

We can reproduce by running below resources by providing some meaningful zip to the function.

resource "aws_lambda_function" "waf_spam_list" {
filename = "lambda.zip"
function_name = "waf_spam_list"
role = "arn:aws:iam::xxxxxxxxxxxx:role/xxxxxxxxxxxxx"
handler = "index.handler"
source_code_hash = "${base64sha256(file("lambda.zip"))}"
runtime = "nodejs4.3"
timeout = "59"
}

resource "aws_cloudwatch_event_rule" "waf-spam-update" {
name = "waf-spam-update"
depends_on = ["aws_lambda_function.waf_spam_list"]
schedule_expression = "rate(1 minute)"
}

resource "aws_cloudwatch_event_target" "waf-spam-target" {
target_id = "waf-spam-target"
rule = "${aws_cloudwatch_event_rule.waf-spam-update.name}"
arn = "${aws_lambda_function.waf_spam_list.arn}"
input = <<INPUT
{ some json input }
INPUT
}

@byrneo
Copy link

byrneo commented May 15, 2017

I'm experiencing this issue also. Tried 0.9.5 with same result.

@longwave
Copy link

longwave commented Jun 6, 2017

I have successfully set up a WAF with rules updated in a Lambda function and triggered by CloudWatch, very similar to the above example.

Have you added an aws_lambda_permission resource to allow CloudWatch to trigger the Lambda function? See https://www.terraform.io/docs/providers/aws/r/lambda_permission.html

resource "aws_lambda_permission" "waf-spam-update" {
  statement_id = "waf-spam-update"
  action = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.waf_spam_list.function_name}"
  principal = "events.amazonaws.com"
  source_arn = "${aws_cloudwatch_event_rule.waf-spam-update.arn}"
}

@byrneo
Copy link

byrneo commented Jun 13, 2017 via email

@egarbi
Copy link
Contributor

egarbi commented Jul 24, 2017

@byrneo I disagree, the workaround suggested by @longwave worked for me

@SanchitBansal
Copy link

SanchitBansal commented Dec 9, 2017

I am facing the same issue, terraform is giving "created successful" but it is not reflecting actually on aws console. @SandyFox did it work for you?

@SanchitBansal
Copy link

There is one more strange thing, as the permission didn't reflect through terraform, then I applied the different permission manually through aws console and then tried to execute the terraform state again. Ideally it should show change but terraform gave "No changes" output. It clearly signifies that permissions are not being managed by terraform appropriately.

@s-nakka
Copy link
Author

s-nakka commented Dec 9, 2017

@SanchitBansal I didn't get a chance to test it later since my job accomplished by the manual change for now ;) . I will let you know if there is any progress from my end.

@jlsjonas
Copy link

Note: please make sure the "source_arn" is defined, use count/similar if you need multiple.
It didn't work for me without being defined, even though it's optional; beware!

@SanchitBansal
Copy link

@jlsjonas yes I even tried with "source_arn" parameter but no luck.

@snasirca
Copy link

I was having the same problem and ultimately here is the code that worked for me in its entirety (minus the iam_role and iam_role_policy):

NOTE: I added target_id and depends_on and that was what worked for me. Not sure which of those I needed. Haven't gone through a process of elimination to see which one is necessary and I'm a novice at terraform so can't say without further experimentation.

data "archive_file" "function" {
  type = "zip"
  source_file = "${path.module}/index.js"
  output_path = "${path.module}/function.zip"
}

resource "aws_lambda_function" "demo_lambda" {
  function_name = "demo_lambda"
  handler = "index.handler"
  runtime = "nodejs6.10"
  filename = "function.zip"
  source_code_hash = "${base64sha256(file("function.zip"))}"
  role = "${aws_iam_role.lambda_exec_role.arn}"
}

resource "aws_cloudwatch_event_rule" "demo_lambda_every_one_minute" {
  name = "demo_lambda_every_one_minute"
  // Worked for me after I added `depends_on`
  depends_on = [
    "aws_lambda_function.demo_lambda"
  ]
  schedule_expression = "rate(1 minute)"
}

resource "aws_cloudwatch_event_target" "demo_lambda" {
  target_id = "demo_lambda" // Worked for me after I added `target_id`
  rule = "${aws_cloudwatch_event_rule.demo_lambda_every_one_minute.name}"
  arn = "${aws_lambda_function.demo_lambda.arn}"
}

resource "aws_lambda_permission" "demo_lambda_every_one_minute" {
  statement_id = "AllowExecutionFromCloudWatch"
  action = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.demo_lambda.function_name}"
  principal = "events.amazonaws.com"
  source_arn = "${aws_cloudwatch_event_rule.demo_lambda_every_one_minute.arn}"
}

CC: hashicorp/terraform-provider-aws#756

@exNewbie
Copy link

exNewbie commented Mar 9, 2018

resource "aws_lambda_permission" "demo_lambda_every_one_minute" {
  statement_id = "AllowExecutionFromCloudWatch"
  action = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.demo_lambda.function_name}"
  principal = "events.amazonaws.com"
  source_arn = "${aws_cloudwatch_event_rule.demo_lambda_every_one_minute.arn}"
}

this part does the trick. I dont need additions on aws_cloudwatch_event_rule and aws_cloudwatch_event_target

@sinahwz
Copy link

sinahwz commented Mar 13, 2018

Worked as @snasirca, although I didnt have to include the depends_on and target_id.
Basically target_id is automatically computed if not provided. But if you provide it, it shouldnt be longer than 64 characters, else it throws an error.

@trjate
Copy link

trjate commented May 26, 2018

@exNewbie Thanks, this is what I was missing!

@chenjian263941
Copy link

@jlsjonas How to use the similar grammar with terraform you Mentioned?

@apparentlymart apparentlymart added this to the v0.12.0 milestone Oct 29, 2018
@brunordias
Copy link

Worked when I put target_id in aws_cloudwatch_event_target with the same value from name in aws_cloudwatch_event_rule. When Terraform put the random value in target_id this don't work.

@ghost
Copy link

ghost commented Sep 6, 2019

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@hashicorp hashicorp locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests