简体   繁体   English

我可以通过 Terraform 将 CloudWatch 事件规则附加到“内置目标”吗?

[英]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.此处的目标是创建 EBS 卷的计划快照。 Looking at Terraform's documentation for aws_cloudwatch_event_target it doesn't seem possible, but I could be missing something.查看aws_cloudwatch_event_target Terraform 文档似乎不可能,但我可能会遗漏一些东西。

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 .的CloudWatch活动内建目标只是似乎需要的输入参数,以及其示出了用于在例如添加消息到SNS队列中ARN aws_cloudwatch_event_rule或在发送到室壁运动流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.显然,您可能希望从您创建它们的资源中获取 EBS 卷 ID,但这超出了问题的范围。 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.在 AWS 控制台中创建规则然后查看aws events list-targets-by-rule的输出后,我还猜测了 ARN,它似乎将规则名称添加到目标的 ARN 中,但可能不会永远是真实的/必要的。

The previous answer was enough to get everything except for the IAM permissions on the event targets (ie go into the console, edit the rule, and in "Step 2", for the "AWS Permissions" section, create a new role, etc).前面的答案足以获得除事件目标上的 IAM 权限之外的所有内容(即进入控制台,编辑规则,并在“第 2 步”中的“AWS 权限”部分,创建新角色等) . To get this working in terraform, I just added a few resources:为了让它在 terraform 中工作,我只是添加了一些资源:

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}"
}

I was able to get this working entirely in terraform by tweaking this response provided by D Swartz .通过调整D Swartz提供的响应,我能够完全在 terraform 中工作。 I had to modify the aws_cloudwatch_event_target resource in a few ways:我不得不通过以下几种方式修改aws_cloudwatch_event_target资源:

  1. The arn field needs to point to the target/create-snapshot event instead of the action/EBSCreateSnapshot automation action. arn字段需要指向target/create-snapshot事件,而不是action/EBSCreateSnapshot自动化操作。

  2. The input field needs to be set to the desired volume's id rather than its arn . input字段需要设置为所需卷的id而不是其arn

  3. The role_arn needs to be set to the arn of the aws_iam_role that will be running the event. role_arn需要设置为将运行事件的aws_iam_rolearn

The updated aws_cloudwatch_event_target resource looks like this:更新后的aws_cloudwatch_event_target资源如下所示:

resource "aws_cloudwatch_event_target" "example_event_target" {
  target_id = "example"
  rule = "${aws_cloudwatch_event_rule.snapshot_example.name}"
  arn = "arn:aws:events:${var.aws_region}:${var.account_id}:target/create-snapshot"
  input = "${jsonencode("${aws_ebs_volume.example.id}")}"
  role_arn = "${aws_iam_role.snapshot_permissions.arn}"
}

Full code snippet below:完整代码片段如下:

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:events:${var.aws_region}:${var.account_id}:target/create-snapshot"
  input = "${jsonencode("${aws_ebs_volume.example.id}")}"
  role_arn = "${aws_iam_role.snapshot_permissions.arn}"
}

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}"
}

edit: I'm not entirely clear if this is directly supported by AWS or not - based on their documentation it seems like this may not be an intended feature:编辑:我不完全清楚这是否由 AWS 直接支持 - 根据他们的文档,这似乎不是预期的功能:

Creating rules with built-in targets is supported only in the AWS Management Console.仅 AWS 管理控制台支持使用内置目标创建规则。

I came up with this solution which is compatible with AWS CloudWatch Rules and Amazon EventBridge:我想出了这个与 AWS CloudWatch Rules 和 Amazon EventBridge 兼容的解决方案:

resource "aws_cloudwatch_event_rule" "volume_snapshot_rule" {
  name                = "ebs-volume-snapshot"
  description         = "Create an EBS volume snapshot every 6 hours"
  schedule_expression = "rate(6 hours)"
}

resource "aws_cloudwatch_event_target" "volume_snapshot_target" {
  target_id = "ebs-volume-snapshot-target"
  rule      = aws_cloudwatch_event_rule.volume_snapshot_rule.name
  arn       = "arn:aws:events:eu-central-1:${data.aws_caller_identity.current.account_id}:target/create-snapshot"
  role_arn  = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/create-ebs-snapshot"
  input     = "\"${aws_ebs_volume.storage.id}\""
}

data "aws_caller_identity" "current" {}

And for the IAM role对于 IAM 角色

resource "aws_iam_role" "create_ebs_snapshot" {
  name = "create-ebs-snapshot"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "events.amazonaws.com"
        }
      },
    ]
  })

  inline_policy {
    name = "policy"

    policy = jsonencode({
      Version = "2012-10-17"
      Statement = [
        {
          Action   = ["ec2:CreateSnapshot"]
          Effect   = "Allow"
          Resource = "*"
        },
      ]
    })
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 Terraform 中的不同输入为 lambda function 创建一个 cloudwatch 事件规则目标 - Create a cloudwatch event rule target to a lambda function with different inputs in Terraform 通过 terraform 创建用于任务状态更改的 Cloudwatch 事件规则 - Create Cloudwatch event rule for task state change via terraform 通过 cloudformation 为 fargate launchtype 任务创建 cloudwatch 事件规则的“目标” - creating a 'Target' for a cloudwatch event rule via cloudformation for a fargate launchtype task 将特定事件附加到 cloudwatch 事件规则 - Attach a specific event to a cloudwatch events rule 使用Terraform将ECS任务ARN注入AWS Cloudwatch事件规则 - Inject ECS Task ARN into AWS Cloudwatch Event Rule using Terraform 带有事件模式的 Terraform AWS Cloudwatch 规则未正确更新 - Terraform AWS Cloudwatch Rule with Event Pattern incorrectly updated Terraform 不会在 cloudwatch 事件目标上添加日志组名称 - Terraform doesn't add log group name on cloudwatch event target 如何通过 Terraform 在 API Gateway v2 API 上启用 CloudWatch 日志记录? - How can I enable CloudWatch logging on an API Gateway v2 API via Terraform? 通过由Cloudwatch事件规则分类的AWS Lambda标记EMR集群 - Tagging EMR cluster via an AWS Lambda tiggered by a Cloudwatch event rule terraform 计划:错误:尝试创建 cloudwatch 事件目标时,sqs_target 应该是一个列表 - terraform plan: error: sqs_target should be a list when trying to create a cloudwatch event target
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM