概要
AWS Configを利用するための一連のリソースを作成します。
- AWS Configの有効化
- 設定はマネコンで有効化したとき同様のシンプルなものにします
- Config Rule
- ここではサンプルとしてrestrected_sshルールと、修復アクションを設定します
- Slack通知用Event Bridge Rule
S3バケット作成
- バケット名、バケットポリシーは、マネコンでconfigを作成したときに自動生成されるものを踏襲しています(変えてもOKです)
- 以下は任意です
- SSE暗号化
- パブリックアクセスブロックON
main.tf
resource "aws_s3_bucket" "config" {
bucket = "config-bucket-123456789012"
server_side_encryption_configuration {
rule {
bucket_key_enabled = false
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
}
resource "aws_s3_bucket_public_access_block" "config" {
bucket = aws_s3_bucket.config.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_policy" "config" {
bucket = aws_s3_bucket.config.bucket
policy = jsonencode(
{
Version = "2012-10-17",
Statement = [
{
Sid = "AWSConfigBucketPermissionsCheck",
Effect = "Allow",
Principal = {
"Service" = "config.amazonaws.com"
},
Action = "s3:GetBucketAcl",
Resource = aws_s3_bucket.config.arn
},
{
Sid = "AWSConfigBucketExistenceCheck",
Effect = "Allow",
Principal = {
"Service" = "config.amazonaws.com"
},
Action = "s3:ListBucket",
Resource = aws_s3_bucket.config.arn
},
{
Sid = "AWSConfigBucketDelivery",
Effect = "Allow",
Principal = {
"Service" = "config.amazonaws.com"
},
Action = "s3:PutObject",
Resource = "${aws_s3_bucket.config.arn}/AWSLogs/123456789012/Config/*",
Condition = {
StringEquals = {
"s3:x-amz-acl" = "bucket-owner-full-control"
}
}
}
]
}
)
}
config作成
- マネコンでconfigを有効化するとサービスロールが自動生成されますが、terraformから有効化すると生成されないので明示的に作成します
- デリバリチャンネル名は、マネコンで作成したときに自動設定されるもの("default")を踏襲します
resource "aws_iam_service_linked_role" "config" {
aws_service_name = "config.amazonaws.com"
}
resource "aws_config_delivery_channel" "main" {
name = "default"
s3_bucket_name = aws_s3_bucket.config.bucket
}
resource "aws_config_configuration_recorder" "main" {
role_arn = aws_iam_service_linked_role.config.arn
recording_group {
all_supported = true
include_global_resource_types = true
resource_types = []
}
}
resource "aws_config_configuration_recorder_status" "main" {
name = "default"
is_enabled = true
depends_on = [aws_config_delivery_channel.main]
}
修復アクション用IAMロール/ポリシー作成
- 詳細は省きます
- IAMロール
- 信頼ポリシーで
ssm.amazonaws.com
サービスを許可します
- 信頼ポリシーで
- IAMポリシー
-
Resource = "*"
でec2:RevokeSecurityGroupIngress
を許可します
-
configルール/修復アクション作成
- 修復アクション
- 試行回数は最低限(1分後に1回)としています
- 修復アクションのパラメータで、
GroupId: RESOURCE_ID
を指定することで、すべてのリソースが対象になります - AutomationAssumeRoleに作成したIAMロールのARNを指定します
resource "aws_config_config_rule" "restricted_ssh" {
description = "Checks whether security groups that are in use disallow unrestricted incoming SSH traffic."
input_parameters = jsonencode({})
name = "restricted-ssh"
scope {
compliance_resource_types = [
"AWS::EC2::SecurityGroup",
]
}
source {
owner = "AWS"
source_identifier = "INCOMING_SSH_DISABLED"
}
}
resource "aws_config_remediation_configuration" "restricted_ssh" {
automatic = true
config_rule_name = "restricted-ssh"
maximum_automatic_attempts = 1
retry_attempt_seconds = 60
target_id = "AWS-DisablePublicAccessForSecurityGroup"
target_type = "SSM_DOCUMENT"
target_version = "1"
parameter {
name = "AutomationAssumeRole"
static_value = aws_iam_role.auto_remediation.arn
}
parameter {
name = "GroupId"
resource_value = "RESOURCE_ID"
}
}
Slack通知用Event Bridge Rule
- Chatbot - SNSトピック - Event Bridge Ruleを連携します
- Chatbot
- Terraform未サポートのため手動作成します
- Chatbot, SNSトピックの作成/連携は省略します
- Event Bridge Rule
- Security Hubを有効化している場合は、Security Hubの通知のフィルタリングを検討します
resource "aws_cloudwatch_event_rule" "awsconfig" {
event_pattern = jsonencode(
{
detail-type = [
"Config Rules Compliance Change",
]
source = [
"aws.config",
]
}
)
name = "config-notification-rule"
is_enabled = true
}
resource "aws_cloudwatch_event_target" "config" {
arn = "arn:aws:sns:ap-northeast-1:123456789012:config-notification-topic"
rule = aws_cloudwatch_event_rule.config.id
}