[英]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
资源:
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
自动化操作。
The input
field needs to be set to the desired volume's id
rather than its arn
. input
字段需要设置为所需卷的id
而不是其arn
。
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_role
的arn
。
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.