我可以通过 Terraform 将 CloudWatch 事件规则附加到 'built-in target' 吗?
Can I attach a CloudWatch event rule to a 'built-in target' via Terraform?
此处的目标是创建 EBS 卷的计划快照。查看 Terraform 的 aws_cloudwatch_event_target
文档似乎不可能,但我可能遗漏了一些东西。
Cloudwatch Events 内置目标似乎只需要一个输入参数以及在 aws_cloudwatch_event_rule
or sending to a Kinesis stream in aws_cloudwatch_event_target
.
的示例中显示的用于将消息添加到 SNS 队列的 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 控制台中创建规则然后查看 aws events list-targets-by-rule
的输出后,我还猜测了 ARN,它似乎将规则名称添加到目标的 ARN,但可能并不总是 true/necessary.
前面的答案足以获得除事件目标上的 IAM 权限之外的所有内容(即进入控制台,编辑规则,并在 "Step 2" 中,对于 "AWS Permissions" 部分,创建新角色等)。为了让它在 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}"
}
通过调整 provided by D Swartz,我能够完全在 terraform 中运行它。我不得不通过几种方式修改 aws_cloudwatch_event_target
资源:
arn
字段需要指向 target/create-snapshot
事件而不是 action/EBSCreateSnapshot
自动化操作。
input
字段需要设置为所需卷的 id
而不是其 arn
。
需要将 role_arn
设置为 aws_iam_role
的 arn
,这将是 运行 事件。
更新后的 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}"
}
编辑: 我不完全清楚这是否由 AWS 直接支持 - 基于 their documentation 看来这可能不是预期的功能:
Creating rules with built-in targets is supported only in the AWS Management Console.
我想出了这个与 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" {}
对于 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 = "*"
},
]
})
}
}
此处的目标是创建 EBS 卷的计划快照。查看 Terraform 的 aws_cloudwatch_event_target
文档似乎不可能,但我可能遗漏了一些东西。
Cloudwatch Events 内置目标似乎只需要一个输入参数以及在 aws_cloudwatch_event_rule
or sending to a Kinesis stream in aws_cloudwatch_event_target
.
所以我们应该能够做这样的事情:
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 控制台中创建规则然后查看 aws events list-targets-by-rule
的输出后,我还猜测了 ARN,它似乎将规则名称添加到目标的 ARN,但可能并不总是 true/necessary.
前面的答案足以获得除事件目标上的 IAM 权限之外的所有内容(即进入控制台,编辑规则,并在 "Step 2" 中,对于 "AWS Permissions" 部分,创建新角色等)。为了让它在 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_event_target
资源:
arn
字段需要指向target/create-snapshot
事件而不是action/EBSCreateSnapshot
自动化操作。input
字段需要设置为所需卷的id
而不是其arn
。需要将
role_arn
设置为aws_iam_role
的arn
,这将是 运行 事件。
更新后的 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}"
}
编辑: 我不完全清楚这是否由 AWS 直接支持 - 基于 their documentation 看来这可能不是预期的功能:
Creating rules with built-in targets is supported only in the AWS Management Console.
我想出了这个与 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" {}
对于 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 = "*"
},
]
})
}
}