Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create WebACL for SRE bot. #600

Merged
merged 3 commits into from
Jul 31, 2024
Merged

Create WebACL for SRE bot. #600

merged 3 commits into from
Jul 31, 2024

Conversation

sylviamclaughlin
Copy link
Contributor

@sylviamclaughlin sylviamclaughlin commented Jul 30, 2024

Summary | Résumé

Put in terraform the WebACL for SRE bot. Also, add a feature so that if 1000 requests from the same IP address come within 5 minutes, block that IP address. We can delete the existing one after since it was put together for testing.

@sylviamclaughlin sylviamclaughlin self-assigned this Jul 30, 2024
@sylviamclaughlin sylviamclaughlin requested a review from a team July 30, 2024 23:05
Copy link

Production: terraform

✅   Terraform Init: success
✅   Terraform Validate: success
✅   Terraform Format: success
✅   Terraform Plan: success
✅   Conftest: success

Plan: 5 to add, 1 to change, 0 to destroy
Show summary
CHANGE NAME
add aws_cloudwatch_log_group.sre_bot_waf_log_group
aws_wafv2_ip_set.blocked_ips
aws_wafv2_web_acl.sre-bot
aws_wafv2_web_acl_association.sre-bot
aws_wafv2_web_acl_logging_configuration.sre-bot
update aws_iam_role.sre-bot
Show plan
Resource actions are indicated with the following symbols:
  + create
  ~ update in-place

Terraform will perform the following actions:

  # aws_cloudwatch_log_group.sre_bot_waf_log_group will be created
  + resource "aws_cloudwatch_log_group" "sre_bot_waf_log_group" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "sre-bot-waf-log-group"
      + name_prefix       = (known after apply)
      + retention_in_days = 0
      + skip_destroy      = false
      + tags_all          = (known after apply)
    }

  # aws_iam_role.sre-bot will be updated in-place
  ~ resource "aws_iam_role" "sre-bot" {
      ~ assume_role_policy    = jsonencode(
          ~ {
              ~ Statement = [
                  ~ {
                      ~ Principal = {
                          - AWS     = "arn:aws:sts::283582579564:assumed-role/AWSReservedSSO_AWSAdministratorAccess_fdd017a84f0012e7/[email protected]" -> null
                            # (1 unchanged element hidden)
                        }
                        # (2 unchanged elements hidden)
                    },
                ]
                # (1 unchanged element hidden)
            }
        )
        id                    = "sre-bot-ecs-role"
        name                  = "sre-bot-ecs-role"
        tags                  = {
            "CostCentre" = "sre-bot"
        }
        # (8 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

  # aws_wafv2_ip_set.blocked_ips will be created
  + resource "aws_wafv2_ip_set" "blocked_ips" {
      + addresses          = [
          + "103.121.39.54/32",
          + "144.126.228.231/32",
          + "180.158.42.112/32",
          + "222.180.82.37/32",
        ]
      + arn                = (known after apply)
      + description        = "List of IP addresses for the SRE bot that are blocked due to attacks"
      + id                 = (known after apply)
      + ip_address_version = "IPV4"
      + lock_token         = (known after apply)
      + name               = "sre-bot-blocked-ips"
      + scope              = "REGIONAL"
      + tags_all           = (known after apply)
    }

  # aws_wafv2_web_acl.sre-bot will be created
  + resource "aws_wafv2_web_acl" "sre-bot" {
      + application_integration_url = (known after apply)
      + arn                         = (known after apply)
      + capacity                    = (known after apply)
      + description                 = "WAF Web ACL for SRE Bot"
      + id                          = (known after apply)
      + lock_token                  = (known after apply)
      + name                        = "sre-bot"
      + scope                       = "REGIONAL"
      + tags                        = {
          + "Name" = "sre-bot"
        }
      + tags_all                    = {
          + "Name" = "sre-bot"
        }

      + default_action {
          + allow {
            }
        }

      + rule {
          + name     = "Blocked_ips"
          + priority = 5

          + action {

              + block {
                }
            }

          + statement {

              + ip_set_reference_statement {
                  + arn = (known after apply)
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "Blocked_ips"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "rate-limit-rule"
          + priority = 7

          + action {

              + block {
                }
            }

          + statement {

              + rate_based_statement {
                  + aggregate_key_type    = "IP"
                  + evaluation_window_sec = 300
                  + limit                 = 1000
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "rateLimitRule"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "APIRatesEvaluation"
          + priority = 0

          + action {

              + count {
                }
            }

          + statement {

              + rate_based_statement {
                  + aggregate_key_type    = "CONSTANT"
                  + evaluation_window_sec = 300
                  + limit                 = 500

                  + scope_down_statement {

                      + byte_match_statement {
                          + positional_constraint = "STARTS_WITH"
                          + search_string         = "/"

                          + field_to_match {

                              + uri_path {}
                            }

                          + text_transformation {
                              + priority = 0
                              + type     = "NONE"
                            }
                        }
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "APIRatesEvaluation"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AuthorizedEndpoints"
          + priority = 6

          + action {

              + count {
                }
            }

          + statement {
              + and_statement {
                  + statement {

                      + not_statement {
                          + statement {

                              + byte_match_statement {
                                  + positional_constraint = "STARTS_WITH"
                                  + search_string         = "/login"

                                  + field_to_match {

                                      + uri_path {}
                                    }

                                  + text_transformation {
                                      + priority = 0
                                      + type     = "NORMALIZE_PATH"
                                    }
                                }
                            }
                        }
                    }
                  + statement {

                      + not_statement {
                          + statement {

                              + byte_match_statement {
                                  + positional_constraint = "STARTS_WITH"
                                  + search_string         = "/logout"

                                  + field_to_match {

                                      + uri_path {}
                                    }

                                  + text_transformation {
                                      + priority = 0
                                      + type     = "NONE"
                                    }
                                }
                            }
                        }
                    }
                  + statement {

                      + not_statement {
                          + statement {

                              + byte_match_statement {
                                  + positional_constraint = "STARTS_WITH"
                                  + search_string         = "/auth"

                                  + field_to_match {

                                      + uri_path {}
                                    }

                                  + text_transformation {
                                      + priority = 0
                                      + type     = "NONE"
                                    }
                                }
                            }
                        }
                    }
                  + statement {

                      + not_statement {
                          + statement {

                              + byte_match_statement {
                                  + positional_constraint = "STARTS_WITH"
                                  + search_string         = "/geolocate"

                                  + field_to_match {

                                      + uri_path {}
                                    }

                                  + text_transformation {
                                      + priority = 0
                                      + type     = "NONE"
                                    }
                                }
                            }
                        }
                    }
                  + statement {

                      + not_statement {
                          + statement {

                              + byte_match_statement {
                                  + positional_constraint = "STARTS_WITH"
                                  + search_string         = "/hook"

                                  + field_to_match {

                                      + uri_path {}
                                    }

                                  + text_transformation {
                                      + priority = 0
                                      + type     = "NONE"
                                    }
                                }
                            }
                        }
                    }
                  + statement {

                      + not_statement {
                          + statement {

                              + byte_match_statement {
                                  + positional_constraint = "STARTS_WITH"
                                  + search_string         = "/version"

                                  + field_to_match {

                                      + uri_path {}
                                    }

                                  + text_transformation {
                                      + priority = 0
                                      + type     = "NONE"
                                    }
                                }
                            }
                        }
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AuthorizedEndpoints"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AWS-AWSManagedRulesAmazonIpReputationList"
          + priority = 4

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesAmazonIpReputationList"
                  + vendor_name = "AWS"
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AWS-AWSManagedRulesAmazonIpReputationList"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AWS-AWSManagedRulesCommonRuleSet"
          + priority = 1

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesCommonRuleSet"
                  + vendor_name = "AWS"
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AWS-AWSManagedRulesCommonRuleSet"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AWS-AWSManagedRulesKnownBadInputsRuleSet"
          + priority = 2

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesKnownBadInputsRuleSet"
                  + vendor_name = "AWS"
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AWS-AWSManagedRulesKnownBadInputsRuleSet"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AWSManagedRulesLinuxRuleSet"
          + priority = 3

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesLinuxRuleSet"
                  + vendor_name = "AWS"
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AWSManagedRulesLinuxRuleSet"
              + sampled_requests_enabled   = true
            }
        }

      + visibility_config {
          + cloudwatch_metrics_enabled = true
          + metric_name                = "sre-bot"
          + sampled_requests_enabled   = true
        }
    }

  # aws_wafv2_web_acl_association.sre-bot will be created
  + resource "aws_wafv2_web_acl_association" "sre-bot" {
      + id           = (known after apply)
      + resource_arn = "arn:aws:elasticloadbalancing:ca-central-1:283582579564:loadbalancer/app/sre-bot/ffb0cf10e879efc8"
      + web_acl_arn  = (known after apply)
    }

  # aws_wafv2_web_acl_logging_configuration.sre-bot will be created
  + resource "aws_wafv2_web_acl_logging_configuration" "sre-bot" {
      + id                      = (known after apply)
      + log_destination_configs = (known after apply)
      + resource_arn            = (known after apply)
    }

Plan: 5 to add, 1 to change, 0 to destroy.

Warning: Argument is deprecated

  with module.sre_bot_bucket.aws_s3_bucket.this,
  on .terraform/modules/sre_bot_bucket/S3/main.tf line 8, in resource "aws_s3_bucket" "this":
   8: resource "aws_s3_bucket" "this" {

Use the aws_s3_bucket_server_side_encryption_configuration resource instead

(and 6 more similar warnings elsewhere)

─────────────────────────────────────────────────────────────────────────────

Saved the plan to: plan.tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "plan.tfplan"
Show Conftest results
WARN - plan.json - main - Missing Common Tags: ["aws_acm_certificate.sre_bot"]
WARN - plan.json - main - Missing Common Tags: ["aws_cloudwatch_log_group.sre-bot_group"]
WARN - plan.json - main - Missing Common Tags: ["aws_cloudwatch_log_group.sre_bot_dns"]
WARN - plan.json - main - Missing Common Tags: ["aws_cloudwatch_log_group.sre_bot_waf_log_group"]
WARN - plan.json - main - Missing Common Tags: ["aws_cloudwatch_metric_alarm.sre_bot_error"]
WARN - plan.json - main - Missing Common Tags: ["aws_cloudwatch_metric_alarm.sre_bot_warning"]
WARN - plan.json - main - Missing Common Tags: ["aws_dynamodb_table.aws_access_requests_table"]
WARN - plan.json - main - Missing Common Tags: ["aws_dynamodb_table.sre_bot_data"]
WARN - plan.json - main - Missing Common Tags: ["aws_dynamodb_table.webhooks_table"]
WARN - plan.json - main - Missing Common Tags: ["aws_ecr_repository.sre-bot"]
WARN - plan.json - main - Missing Common Tags: ["aws_ecs_cluster.sre-bot"]
WARN - plan.json - main - Missing Common Tags: ["aws_ecs_service.main"]
WARN - plan.json - main - Missing Common Tags: ["aws_ecs_task_definition.sre-bot"]
WARN - plan.json - main - Missing Common Tags: ["aws_iam_policy.geodb_refresh_policy"]
WARN - plan.json - main - Missing Common Tags: ["aws_iam_policy.sre-bot_secrets_manager"]
WARN - plan.json - main - Missing Common Tags: ["aws_iam_policy.sre_bot_bucket"]
WARN - plan.json - main - Missing Common Tags: ["aws_iam_role.sre-bot"]
WARN - plan.json - main - Missing Common Tags: ["aws_lb.sre_bot"]
WARN - plan.json - main - Missing Common Tags: ["aws_lb_listener.sre_bot_listener"]
WARN - plan.json - main - Missing Common Tags: ["aws_lb_target_group.sre_bot"]
WARN - plan.json - main - Missing Common Tags: ["aws_route53_health_check.sre_bot_healthcheck"]
WARN - plan.json - main - Missing Common Tags: ["aws_route53_resolver_query_log_config.sre_bot"]
WARN - plan.json - main - Missing Common Tags: ["aws_route53_zone.sre_bot"]
WARN - plan.json - main - Missing Common Tags:...

@sylviamclaughlin sylviamclaughlin merged commit 5aa41de into main Jul 31, 2024
6 checks passed
@sylviamclaughlin sylviamclaughlin deleted the feat/recreate_web_acl branch July 31, 2024 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants