2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[terraform] aws config

Posted at

概要

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
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?