この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、コンサルティング部の後藤です。
先日CloudWatchイベントルールの作成をTerraformで行いました。その時、ターゲットを「別アカウントのイベントバスを指定」にする必要があったのですが、Terraformで設定する際に少し分かりにくかったので備忘録になります。
Terraformバージョン
本記事は以下のバージョンを使用して実行しています。
$ terraform --version
Terraform v0.12.29
+ provider.aws v3.4.0
CloudWatchイベント作成
TerraformでCloudWatchイベントを作成する場合、イベントソースとターゲットでresourceが異なります。
まず、イベントソースのみ指定したルールを作成します。今回はイベントソースとしてGuardDutyを指定しています。
resource "aws_cloudwatch_event_rule" "rule" {
name = "test-rule"
event_pattern = <<EOF
{
"source" : [
"aws.guardduty"
],
"detail-type": [
"GuardDuty Finding"
]
}
EOF
}
Terraformを実行してマネージドコンソールを確認すると、ルールが作成されていることがわかります。
CloudWatchイベントのターゲットを設定
TerraformでCloudWatchイベントのターゲットを設定する場合、resource "aws_cloudwatch_event_target"
を使用します。
ドキュメントがこちらになるのですが、ECSやKinesis、Batch等をターゲットにした設定値はあるのに対して、「別アカウントのイベントバスを指定」で使用する設定値が見当たらないので、一度手動で設定し、Terraformにimportしてどの項目を設定すれば良いか確認してみました。
ターゲット設定をTerraformにimportするためにtarget-idが必要になるため、AWS CLIで取得します。
$ aws events list-targets-by-rule --rule 【ルール名】
{
"Targets": [
{
"Id": "Id441716527535", # ここ!
"Arn": "arn:aws:events:ap-northeast-1:123456789010:event-bus/default",
"RoleArn": "arn:aws:iam::010987654321:role/service-role/AWS_Events_Invoke_Event_Bus_1500696013"
}
]
}
Terraform importを実行する前にresourceを以下のように定義しました。
resource "aws_cloudwatch_event_target" "target" {
rule = "hoge"
arn = ""
}
取得したtarget-idを使用してimportを実行します。
$ terraform import aws_cloudwatch_event_target.target 【ルール名】/【target-id】
# 実行例
$ terraform import aws_cloudwatch_event_target.target test-rule/Id441716527535
aws_cloudwatch_event_target.target: Importing from ID "test-rule/Id441716527535"...
aws_cloudwatch_event_target.target: Import prepared!
Prepared aws_cloudwatch_event_target for import
aws_cloudwatch_event_target.target: Refreshing state... [id=test-rule-Id441716527535]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
import後、terraform planで不足している値を確認すると、
# aws_cloudwatch_event_target.target must be replaced
-/+ resource "aws_cloudwatch_event_target" "target" {
- arn = "arn:aws:events:ap-northeast-1:xxxxxxxxx:event-bus/default" -> null
~ id = "test-rule-Id441716527535" -> (known after apply)
- role_arn = "arn:aws:iam::xxxxxxxxxx:role/service-role/AWS_Events_Invoke_Event_Bus_1500696013" -> null
~ rule = "test-rule" -> "hoge" # forces replacement
~ target_id = "Id441716527535" -> (known after apply)
}
arn / rule / role_arn の値だけで「別アカウントのイベントバスを指定」は設定出来そうです。
上記結果を参考に、以下のようなTerraformを書いてみました。
$ cat cw_event.tf
## IAMポリシー作成
resource "aws_iam_policy" "policy" {
name = "cw-test-policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"events:PutEvents"
],
"Resource": [
"arn:aws:events:*:123456789010:event-bus/default"
]
}
]
}
EOF
}
## IAMロール作成
resource "aws_iam_role" "role" {
name = "cw-test-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "events.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
## IAMロールにIAMポリシーをアタッチ
resource "aws_iam_role_policy_attachment" "attach" {
role = aws_iam_role.role.name
policy_arn = aws_iam_policy.policy.arn
}
## CloudWatchイベント作成
resource "aws_cloudwatch_event_rule" "rule" {
name = "test2-rule"
event_pattern = <<EOF
{
"source" : [
"aws.guardduty"
],
"detail-type": [
"GuardDuty Finding"
]
}
EOF
}
## CloudWatchイベントのターゲット設定
resource "aws_cloudwatch_event_target" "target" {
rule = aws_cloudwatch_event_rule.rule.name
arn = "arn:aws:events:ap-northeast-1:662149051709:event-bus/default"
role_arn = aws_iam_role.role.arn
}
AWSマネージドコンソールでターゲットを設定すると自動でIAMロールを作成、設定してくれますが、Terraformでターゲットを設定する場合はIAMロールを作成してあげる必要がありました。
上記Terraformを実行してAWSマネージドコンソールを確認してみると、「別のAWSアカウントのイベントバス」でターゲットが設定されたCloudWatchイベントが作成されていました。
まとめ
TerraformでCloudWatchイベントの作成、ターゲットに「別のAWSアカウントのイベントバス」を指定する方法を紹介しました。かなり小ネタなTipsになりましたが、どなたかのお役に立てば幸いです。