我能否通过 Terraform 将 CloudWatch 事件规则附加到'built-in target'?



这里的目标是创建EBS卷的定时快照。看看Terraform的aws_cloudwatch_event_target文档,这似乎是不可能的,但我可能错过了一些东西。

Cloudwatch Events内置目标似乎只需要一个输入参数以及在aws_cloudwatch_event_rule示例中显示的将消息添加到SNS队列或发送到aws_cloudwatch_event_target中的kineesis流的ARN。

所以我们应该可以这样做:

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

我还没有测试过这个,但它应该工作。显然,您可能希望从创建它们的资源中获取EBS卷id,但这超出了问题的范围。在AWS控制台上创建规则后,我还猜测了ARN,然后查看aws events list-targets-by-rule的输出,其中似乎将规则名称添加到目标的ARN中,但这可能并不总是正确的/必要的。

通过调整D Swartz提供的响应,我能够在terraform中完全工作。我必须以几种方式修改aws_cloudwatch_event_target资源:

  1. arn字段需要指向target/create-snapshot事件,而不是action/EBSCreateSnapshot自动化操作。

  2. input字段需要设置为所需卷的id而不是arn

  3. role_arn需要设置为将要运行事件的aws_iam_rolearn

更新后的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}"
}

下面的完整代码片段:

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:我不完全清楚这是否由AWS直接支持-基于他们的文档,似乎这可能不是一个预期的功能:

仅在AWS Management Console中支持使用内置目标创建规则。

前面的答案足以获得除了事件目标上的IAM权限之外的所有内容(例如,进入控制台,编辑规则,并在"步骤2"中,对于"AWS权限"部分,创建一个新角色等)。为了在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}"
}

我想出了这个与AWS CloudWatch规则和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" {}

对于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 = "*"
        },
      ]
    })
  }
}

相关内容

最新更新