Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I attach a CloudWatch event rule to a 'built-in target' via Terraform?

The goal here is to create scheduled snapshots of EBS volumes. Looking at Terraform's documentation for aws_cloudwatch_event_target it doesn't seem possible, but I could be missing something.

like image 570
ds011591 Avatar asked Aug 16 '16 13:08

ds011591


2 Answers

Cloudwatch Events built-in targets just seem to require an input parameter as well as the ARN that is shown for adding a message to an SNS queue in the example for aws_cloudwatch_event_rule or sending to a Kinesis stream in aws_cloudwatch_event_target.

So we should just be able to do something like this:

resource "aws_cloudwatch_event_target" "ebs_vol_a" {
  target_id = "ebs_vol_a"
  rule = "${aws_cloudwatch_event_rule.snap_ebs.name}"
  arn = "arn:aws:automation:${var.region}:${var.account_id}:action/EBSCreateSnapshot/EBSCreateSnapshot_ebs_vol_a"
  input = "\"arn:aws:ec2:${var.region}:${var.account_id}:volume/vol-${var.ebs_vol_a_id}\""
}

resource "aws_cloudwatch_event_rule" "snap_ebs" {
  name = "snap-ebs-volumes"
  description = "Snapshot EBS volumes"
  schedule_expression = "rate(6 hours)"
}

I haven't yet tested this but it should work. Obviously you probably want to get the EBS volume IDs from the resource you created them but that's beyond the scope of the question. I've also guessed at the ARN after creating a rule in the AWS console and then looking at the output of aws events list-targets-by-rule where it seems to add the rule name to the ARN of the target but that may not always be true/necessary.

like image 126
ydaetskcoR Avatar answered Sep 19 '22 13:09

ydaetskcoR


The previous answer was enough to get everything except for the IAM permissions on the event targets (i.e. go into the console, edit the rule, and in "Step 2", for the "AWS Permissions" section, create a new role, etc). To get this working in terraform, I just added a few resources:

resource "aws_cloudwatch_event_rule" "snapshot_example" {
  name = "example-snapshot-volumes"
  description = "Snapshot EBS volumes"
  schedule_expression = "rate(24 hours)"
}

resource "aws_cloudwatch_event_target" "example_event_target" {
  target_id = "example"
  rule = "${aws_cloudwatch_event_rule.snapshot_example.name}"
  arn = "arn:aws:automation:${var.aws_region}:${var.account_id}:action/EBSCreateSnapshot/EBSCreateSnapshot_example-snapshot-volumes"
  input = "${jsonencode("arn:aws:ec2:${var.aws_region}:${var.account_id}:volume/${aws_ebs_volume.example.id}")}"
}

resource "aws_iam_role" "snapshot_permissions" {
  name = "example"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "automation.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_iam_policy" "snapshot_policy" {
    name        = "example-snapshot-policy"
    description = "grant ebs snapshot permissions to cloudwatch event rule"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:Describe*",
        "ec2:RebootInstances",
        "ec2:StopInstances",
        "ec2:TerminateInstances",
        "ec2:CreateSnapshot"
      ],
      "Resource": "*"
    }
  ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "snapshot_policy_attach" {
    role       = "${aws_iam_role.snapshot_permissions.name}"
    policy_arn = "${aws_iam_policy.snapshot_policy.arn}"
}
like image 45
D Swartz Avatar answered Sep 18 '22 13:09

D Swartz