diff --git a/.github/workflows/dogfood-deploy.yml b/.github/workflows/dogfood-deploy.yml index 3c838e53d2..1b9e5c0d23 100644 --- a/.github/workflows/dogfood-deploy.yml +++ b/.github/workflows/dogfood-deploy.yml @@ -16,25 +16,17 @@ defaults: run: # fail-fast using bash -eo pipefail. See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference shell: bash - working-directory: infrastructure/dogfood/terraform/aws + working-directory: infrastructure/dogfood/terraform/aws-tf-module env: AWS_REGION: us-east-2 ECR_REPOSITORY: fleet-test AWS_IAM_ROLE: arn:aws:iam::160035666661:role/github-actions-role - TF_ACTIONS_WORKING_DIR: infrastructure/dogfood/terraform/aws + TF_ACTIONS_WORKING_DIR: infrastructure/dogfood/terraform/aws-tf-module TF_WORKSPACE: fleet - TF_VAR_fleet_backend_cpu: 512 - TF_VAR_fleet_backend_mem: 4096 - TF_VAR_redis_instance: cache.t3.micro - TF_VAR_fleet_min_capacity: 2 - TF_VAR_fleet_max_capacity: 5 TF_VAR_fleet_image: ${{ github.event.inputs.DOCKER_IMAGE || 'fleetdm/fleet:main' }} - TF_VAR_logging_debug: true TF_VAR_fleet_license: ${{ secrets.DOGFOOD_LICENSE_KEY }} - TF_VAR_cloudwatch_log_retention: 30 - TF_VAR_rds_backup_retention_period: 30 - TF_VAR_extra_security_group_cidrs: '["10.255.1.0/24", "10.255.2.0/24", "10.255.3.0/24"]' + TF_VAR_slack_webhook: ${{ secrets.P1_SLACK_WEBHOOK }} permissions: id-token: write diff --git a/infrastructure/dogfood/terraform/aws-tf-module/.terraform-version b/infrastructure/dogfood/terraform/aws-tf-module/.terraform-version new file mode 100644 index 0000000000..a6a3a43c3a --- /dev/null +++ b/infrastructure/dogfood/terraform/aws-tf-module/.terraform-version @@ -0,0 +1 @@ +1.0.4 \ No newline at end of file diff --git a/infrastructure/dogfood/terraform/aws-tf-module/main.tf b/infrastructure/dogfood/terraform/aws-tf-module/main.tf new file mode 100644 index 0000000000..4be0a2f543 --- /dev/null +++ b/infrastructure/dogfood/terraform/aws-tf-module/main.tf @@ -0,0 +1,256 @@ +provider "aws" { + default_tags { + tags = { + environment = "dogfood" + terraform = "https://github.com/fleetdm/fleet/main/infrastructure/dogfood/terraform" + state = "s3://fleet-terraform-remote-state/fleet" + } + } +} + +terraform { + // these values should match what is bootstrapped in ./remote-state + backend "s3" { + bucket = "fleet-terraform-remote-state" + region = "us-east-2" + key = "fleet" + dynamodb_table = "fleet-terraform-state-lock" + } + required_providers { + aws = { + source = "hashicorp/aws" + version = "4.57.0" + } + } +} + +variable "fleet_license" {} +variable "fleet_image" { + default = "160035666661.dkr.ecr.us-east-2.amazonaws.com/fleet:7408a0df90802fbd602b52015546dd46590051bd" +} + +data "aws_caller_identity" "current" {} + +locals { + customer = "fleet-dogfood" + fleet_image = var.fleet_image # Set this to the version of fleet to be deployed + extra_environment_variables = { + FLEET_LICENSE_KEY = var.fleet_license + FLEET_LOGGING_DEBUG = "true" + FLEET_LOGGING_JSON = "true" + FLEET_MYSQL_MAX_OPEN_CONNS = "50" + FLEET_VULNERABILITIES_DATABASES_PATH = "/home/fleet" + FLEET_OSQUERY_ENABLE_ASYNC_HOST_PROCESSING = "false" + } +} + +module "main" { + source = "github.com/fleetdm/fleet//terraform?ref=main" + certificate_arn = module.acm.acm_certificate_arn + vpc = { + name = local.customer + } + rds_config = { + name = local.customer + snapshot_identifier = "arn:aws:rds:us-east-2:611884880216:cluster-snapshot:a2023-03-06-pre-migration" + } + redis_config = { + name = local.customer + } + ecs_cluster = { + cluster_name = local.customer + } + fleet_config = { + image = local.fleet_image + family = local.customer + awslogs = { + name = local.customer + } + iam = { + role = { + name = "${local.customer}-role" + policy_name = "${local.customer}-iam-policy" + } + execution = { + name = "${local.customer}-execution-role" + policy_name = "${local.customer}-iam-policy-execution" + } + } + extra_iam_policies = concat(module.firehose-logging.fleet_extra_iam_policies, module.osquery-carve.fleet_extra_iam_policies) + extra_execution_iam_policies = concat(module.mdm.extra_execution_iam_policies) + extra_environment_variables = merge(module.mdm.extra_environment_variables, module.firehose-logging.fleet_extra_environment_variables, module.osquery-carve.fleet_extra_environment_variables, local.extra_environment_variables) + extra_secrets = merge(module.mdm.extra_secrets) + } + alb_config = { + name = local.customer + # TODO: This is broken, idk why + #access_logs = { + # bucket = module.logging_alb.log_s3_bucket_id + # prefix = local.customer + # enabled = true + #} + allowed_cidrs = [ + "128.0.0.0/1", + "64.0.0.0/2", + "0.0.0.0/3", + "48.0.0.0/4", + "40.0.0.0/5", + "36.0.0.0/6", + "32.0.0.0/7", + "34.0.0.0/9", + "34.128.0.0/10", + "34.224.0.0/11", + "34.192.0.0/12", + "34.208.0.0/13", + "34.216.0.0/14", + "34.220.0.0/15", + "34.222.0.0/16", + "35.0.0.0/8", + ] + } +} + +module "acm" { + source = "terraform-aws-modules/acm/aws" + version = "4.3.1" + + domain_name = "dogfood.fleetdm.com" + zone_id = aws_route53_zone.main.id + + wait_for_validation = true +} + +resource "aws_route53_zone" "main" { + name = "dogfood.fleetdm.com" +} + +resource "aws_route53_record" "main" { + zone_id = aws_route53_zone.main.id + name = "dogfood.fleetdm.com" + type = "A" + + alias { + name = module.main.byo-vpc.byo-db.alb.lb_dns_name + zone_id = module.main.byo-vpc.byo-db.alb.lb_zone_id + evaluate_target_health = true + } +} + +module "migrations" { + source = "github.com/fleetdm/fleet//terraform/addons/migrations?ref=main" + ecs_cluster = module.main.byo-vpc.byo-db.byo-ecs.service.cluster + task_definition = module.main.byo-vpc.byo-db.byo-ecs.task_definition.family + task_definition_revision = module.main.byo-vpc.byo-db.byo-ecs.task_definition.revision + subnets = module.main.byo-vpc.byo-db.byo-ecs.service.network_configuration[0].subnets + security_groups = module.main.byo-vpc.byo-db.byo-ecs.service.network_configuration[0].security_groups +} + +module "mdm" { + source = "github.com/fleetdm/fleet//terraform/addons/mdm?ref=main" + public_domain_name = "dogfood.fleetdm.com" + apn_secret_name = "${local.customer}-apn" + scep_secret_name = "${local.customer}-scep" + dep_secret_name = "${local.customer}-dep" +} + +module "firehose-logging" { + source = "github.com/fleetdm/fleet//terraform/addons/logging-destination-firehose?ref=main" + osquery_results_s3_bucket = { + name = "${local.customer}-osquery-results-archive" + } + osquery_status_s3_bucket = { + name = "${local.customer}-fleet-osquery-status-archive" + } +} + +module "osquery-carve" { + source = "github.com/fleetdm/fleet//terraform/addons/osquery-carve?ref=main" + osquery_carve_s3_bucket = { + name = "${local.customer}-osquery-carve" + } +} + +module "monitoring" { + source = "github.com/fleetdm/fleet//terraform/addons/monitoring?ref=main" + customer_prefix = local.customer + fleet_ecs_service_name = module.main.byo-vpc.byo-db.byo-ecs.service.name + fleet_min_containers = module.main.byo-vpc.byo-db.byo-ecs.service.desired_count + alb_name = module.main.byo-vpc.byo-db.alb.lb_dns_name + alb_target_group_name = module.main.byo-vpc.byo-db.alb.target_group_names[0] + alb_target_group_arn_suffix = module.main.byo-vpc.byo-db.alb.target_group_arn_suffixes[0] + alb_arn_suffix = module.main.byo-vpc.byo-db.alb.lb_arn_suffix + sns_topic_arns_map = { + alb_httpcode_5xx = [module.notify_slack.slack_topic_arn] + } + mysql_cluster_members = module.main.byo-vpc.rds.cluster_members + # The cloudposse module seems to have a nested list here. + redis_cluster_members = module.main.byo-vpc.redis.member_clusters[0] + acm_certificate_arn = module.acm.acm_certificate_arn +} + +module "logging_alb" { + source = "github.com/fleetdm/fleet//terraform/addons/logging-alb?ref=main" + prefix = local.customer + enable_athena = true +} + +resource "aws_iam_policy" "ecr" { + name = "fleet-ecr-policy" + policy = data.aws_iam_policy_document.ecr.json +} + +data "aws_iam_policy_document" "ecr" { + statement { + actions = [ + "ecr:BatchCheckLayerAvailability", + "ecr:BatchGetImage", + "ecr:GetDownloadUrlForLayer", + "ecr:GetAuthorizationToken" + ] + resources = ["*"] + } + statement { + actions = [ #tfsec:ignore:aws-iam-no-policy-wildcards + "kms:Encrypt*", + "kms:Decrypt*", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + "kms:Describe*" + ] + resources = [aws_kms_key.ecr.arn] + } +} + +resource "aws_ecr_repository" "fleet" { + name = "fleet" + image_tag_mutability = "IMMUTABLE" + + image_scanning_configuration { + scan_on_push = true + } + + encryption_configuration { + encryption_type = "KMS" + kms_key = aws_kms_key.ecr.arn + } +} + +resource "aws_kms_key" "ecr" { + deletion_window_in_days = 10 + enable_key_rotation = true +} + +variable "slack_webhook" { + type = string +} + +module "notify_slack" { + source = "terraform-aws-modules/notify-slack/aws" + version = "5.5.0" + + sns_topic_name = "fleet-dogfood" + + slack_webhook_url = var.slack_webhook + slack_channel = "#help-p1" + slack_username = "monitoring" +}