create vuln processing addon (#10526)

two things here:

1. create addon for use in new modular terraform
2. create vuln processing terraform for legacy terraform, but by default
its disabled
This commit is contained in:
Benjamin Edwards 2023-03-29 08:57:10 -04:00 committed by GitHub
parent 0e2c9bb873
commit 4161ee5679
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 761 additions and 8 deletions

View File

@ -0,0 +1,151 @@
resource "aws_ecs_task_definition" "vuln-processing" {
family = "fleet-vuln-processing"
cpu = 2048
memory = 4096
execution_role_arn = aws_iam_role.main.arn
task_role_arn = aws_iam_role.main.arn
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
container_definitions = jsonencode([
{
name = "fleet-vuln-processing"
image = var.fleet_image
essential = true
command = ["fleet", "vuln_processing"]
networkMode = "awsvpc"
secrets = [
{
name = "FLEET_MYSQL_PASSWORD"
valueFrom = aws_secretsmanager_secret.database_password_secret.arn
}
]
environment = [
{
name = "FLEET_MYSQL_USERNAME"
value = module.aurora_mysql.rds_cluster_master_username
},
{
name = "FLEET_MYSQL_DATABASE"
value = module.aurora_mysql.rds_cluster_database_name
},
{
name = "FLEET_MYSQL_ADDRESS"
value = "${module.aurora_mysql.rds_cluster_endpoint}:3306"
},
{
name = "FLEET_VULNERABILITIES_DATABASES_PATH"
value = "/home/fleet/vuln_data"
},
{
name = "FLEET_LOGGING_DEBUG"
value = "true"
},
{
name = "FLEET_LICENSE_KEY"
value = var.fleet_license
}
],
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = aws_cloudwatch_log_group.backend.name
awslogs-region = data.aws_region.current.name
awslogs-stream-prefix = "fleet-vuln-processing"
}
}
}
])
}
resource "aws_cloudwatch_event_rule" "vuln_processing" {
name_prefix = "${local.name}-vuln-processing"
schedule_expression = "rate(1 hour)"
is_enabled = false
}
resource "aws_cloudwatch_event_target" "vuln_processing" {
arn = aws_ecs_cluster.fleet.arn
rule = aws_cloudwatch_event_rule.vuln_processing.name
role_arn = aws_iam_role.run_cloudwatch.arn
ecs_target {
task_definition_arn = aws_ecs_task_definition.vuln-processing.arn
task_count = 1
launch_type = "FARGATE"
network_configuration {
assign_public_ip = false
subnets = module.vpc.private_subnets
security_groups = [aws_security_group.backend.id]
}
}
}
data "aws_iam_policy_document" "assume_events" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["events.amazonaws.com"]
}
}
}
data "aws_iam_policy_document" "cloudwatch_task" {
statement {
effect = "Allow"
actions = ["iam:PassRole"]
resources = ["*"]
}
statement {
effect = "Allow"
actions = ["ecs:RunTask"]
resources = ["*"]
condition {
test = "ArnEquals"
variable = "ecs:cluster"
values = [aws_ecs_cluster.fleet.arn]
}
}
}
data "aws_iam_policy_document" "assume_role_policy" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ecs-tasks.amazonaws.com"]
}
}
}
resource "aws_iam_role" "run_cloudwatch" {
name = "${local.name}-cloudwatch-run"
assume_role_policy = data.aws_iam_policy_document.assume_events.json
}
resource "aws_iam_policy" "run_cloudwatch" {
name = "${local.name}-cloudwatch-run"
policy = data.aws_iam_policy_document.cloudwatch_task.json
}
resource "aws_iam_role_policy_attachment" "run_cloudwatch" {
role = aws_iam_role.run_cloudwatch.name
policy_arn = aws_iam_policy.run_cloudwatch.arn
}
resource "aws_iam_role_policy_attachment" "ecs_role_attachment" {
role = aws_iam_role.main.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole"
}
resource "aws_iam_role_policy_attachment" "ecs_task" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceEventsRole"
role = aws_iam_role.main.name
}

View File

@ -26,7 +26,7 @@ module "aurora_mysql" { #tfsec:ignore:aws-rds-enable-performance-insights-encryp
name = "${local.name}-mysql" name = "${local.name}-mysql"
engine = "aurora-mysql" engine = "aurora-mysql"
engine_version = "5.7.mysql_aurora.2.10.2" engine_version = "5.7.mysql_aurora.2.10.3"
instance_type = var.db_instance_type instance_type = var.db_instance_type
instance_type_replica = var.db_instance_type instance_type_replica = var.db_instance_type

View File

@ -6,7 +6,7 @@ resource "aws_elasticache_replication_group" "default" {
security_group_ids = [aws_security_group.redis.id, aws_security_group.backend.id] security_group_ids = [aws_security_group.redis.id, aws_security_group.backend.id]
replication_group_id = "${local.prefix}-redis" replication_group_id = "${local.prefix}-redis"
number_cache_clusters = 3 number_cache_clusters = 3
node_type = "cache.m6g.large" node_type = var.redis_instance_type
engine_version = "5.0.6" engine_version = "5.0.6"
port = "6379" port = "6379"
snapshot_retention_limit = 0 snapshot_retention_limit = 0

View File

@ -0,0 +1,3 @@
tag = "6f8abe3"
db_instance_type = "db.t4g.medium"
redis_instance_type = "cache.t4g.small"

View File

@ -25,3 +25,9 @@ variable "db_instance_type" {
type = string type = string
default = "db.r6g.4xlarge" default = "db.r6g.4xlarge"
} }
variable "redis_instance_type" {
description = "the redis instance type to use in loadtesting. default is cache.m6g.large"
type = string
default = "cache.m6g.large"
}

View File

@ -0,0 +1,79 @@
# vulnerability processing addon
This addon adds [external vulnerability processing](https://fleetdm.com/docs/using-fleet/vulnerability-processing#advanced-configuration) to the Fleet deployment.
Be sure to set `FLEET_VULNERABILITIES_DISABLE_SCHEDULE = "true"` or use this modules' `fleet_extra_environment_variables` output to configure
your Fleet server deployment.
Below is an example implementation of the module:
```
module "vulnerability_processing" {
source = "github.com/fleetdm/fleet//terraform/addons/vuln-processing?ref=main"
customer_prefix = "fleet"
ecs_cluster = module.main.byo-vpc.byo-db.byo-ecs.cluster.cluster_arn
vpc_id = module.main.vpc.vpc_id
fleet_config = {
image = "fleetdm/fleet:v4.28.1"
database = {
password_secret_arn = module.main.byo-vpc.secrets.secret_arns["${var.rds_config.name}-database-password"]
user = module.main.byo-vpc.rds.db_instance_username
address = "${module.main.byo-vpc.rds.db_instance_endpoint}:${module.main.byo-vpc.rds.db_instance_port}"
database = module.main.byo-vpc.rds.db_instance_name
}
extra_environment_variables = {
FLEET_LOGGING_DEBUG = "true"
FLEET_LOGGING_JSON = "true"
}
extra_secrets = {
// FLEET_LICENSE_KEY: "secret_manager_license_key_arn" // note needed for some feature of vuln processing
}
networking = {
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
}
}
}
```
## Requirements
[VPC DNS Hostnames](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-hostnames) must be enabled for proper communication to EFS mounted volumes.
## Providers
| Name | Version |
|---------------------------------------------------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |
## Modules
No modules.
## Resources
| Name | Type |
|----------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| [aws_ecs_task_definition.vuln-data-stream](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition) | resource |
| [aws_ecs_task_definition.vuln-processing](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition) | resource |
| [aws_efs_file_system.vuln](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_file_system) | resource |
| [aws_efs_mount_target.vuln](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_mount_target) | resource |
| [aws_cloudwatch_event_rule.vuln_processing](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_target.vuln_processing](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_security_group.efs_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
| [aws_iam_role.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) | resource |
| [aws_iam_role.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|-----------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------|----------|-----------|:--------:|
| <a name="input_customer_prefix"></a> [customer\_prefix](#input\_customer\_prefix) | customer prefix to use to namespace all resources | `string` | `"fleet"` | no |
| <a name="input_ecs_cluster"></a> [ecs\_cluster](#input\_ecs\_cluster) | ECS cluster ARN | `string` | n/a | yes |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | n/a | `string` | n/a | yes |
| <a name="input_fleet_config"></a> [fleet\_config](#input\_fleet\_config) | The configuration object for Fleet itself. Fields that default to null will have their respective resources created if not specified. | `object` | no | yes |
## Outputs
No outputs.

View File

@ -0,0 +1,20 @@
resource "aws_efs_file_system" "vuln" {}
resource "aws_security_group" "efs_security_group" {
name_prefix = "${var.customer_prefix}-efs-mount-sg"
vpc_id = var.vpc_id
// NFS
ingress {
from_port = 2049
to_port = 2049
protocol = "tcp"
security_groups = var.fleet_config.networking.security_groups # Allow traffic from the ECS task security group
}
}
resource "aws_efs_mount_target" "vuln" {
for_each = var.fleet_config.networking.subnets
file_system_id = aws_efs_file_system.vuln.id
subnet_id = each.value
}

View File

@ -0,0 +1,132 @@
data "aws_iam_policy_document" "fleet-execution" {
// allow fleet application to obtain the database password from secrets manager
statement {
effect = "Allow"
actions = ["secretsmanager:GetSecretValue"]
resources = concat(var.fleet_config.database.password_secret_arn, values(var.fleet_config.extra_secrets))
}
}
data "aws_iam_policy_document" "fleet" {
statement {
effect = "Allow"
actions = ["cloudwatch:PutMetricData"]
resources = ["*"]
}
statement {
effect = "Allow"
actions = [
"elasticfilesystem:ClientMount",
"elasticfilesystem:ClientWrite",
"elasticfilesystem:ClientRead",
]
resources = [aws_efs_file_system.vuln.arn]
}
}
data "aws_iam_policy_document" "assume_events" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["events.amazonaws.com", "ecs-tasks.amazonaws.com"]
}
}
}
data "aws_iam_policy_document" "cloudwatch_task" {
statement {
effect = "Allow"
actions = ["iam:PassRole"]
resources = ["*"]
}
statement {
effect = "Allow"
actions = ["ecs:RunTask"]
resources = ["*"]
condition {
test = "ArnEquals"
variable = "ecs:cluster"
values = [var.ecs_cluster]
}
}
}
resource "aws_iam_role" "main" {
count = var.fleet_config.iam_role_arn == null ? 1 : 0
name = var.fleet_config.iam.role.name
description = "IAM role that Fleet application assumes when running in ECS"
assume_role_policy = data.aws_iam_policy_document.assume_events.json
}
resource "aws_iam_policy" "main" {
count = var.fleet_config.iam_role_arn == null ? 1 : 0
name = var.fleet_config.iam.role.policy_name
description = "IAM policy that Fleet application uses to define access to AWS resources"
policy = data.aws_iam_policy_document.fleet.json
}
resource "aws_iam_role_policy_attachment" "main" {
count = var.fleet_config.iam_role_arn == null ? 1 : 0
policy_arn = aws_iam_policy.main[0].arn
role = aws_iam_role.main[0].name
}
resource "aws_iam_role_policy_attachment" "extras" {
for_each = toset(var.fleet_config.extra_iam_policies)
policy_arn = each.value
role = aws_iam_role.main[0].name
}
resource "aws_iam_role_policy_attachment" "execution_extras" {
for_each = toset(var.fleet_config.extra_execution_iam_policies)
policy_arn = each.value
role = aws_iam_role.execution.name
}
resource "aws_iam_policy" "execution" {
name = var.fleet_config.iam.execution.policy_name
description = "IAM policy that Fleet application uses to define access to AWS resources"
policy = data.aws_iam_policy_document.fleet-execution.json
}
resource "aws_iam_role_policy_attachment" "execution" {
policy_arn = aws_iam_policy.execution.arn
role = aws_iam_role.execution.name
}
resource "aws_iam_role" "run_cloudwatch" {
name_prefix = "${var.customer_prefix}-cloudwatch-run"
assume_role_policy = data.aws_iam_policy_document.assume_events.json
}
resource "aws_iam_policy" "run_cloudwatch" {
name_prefix = "${var.customer_prefix}-cloudwatch-run"
policy = data.aws_iam_policy_document.cloudwatch_task.json
}
resource "aws_iam_role_policy_attachment" "run_cloudwatch" {
role = aws_iam_role.run_cloudwatch.name
policy_arn = aws_iam_policy.run_cloudwatch.arn
}
resource "aws_iam_role_policy_attachment" "ecs_role_attachment" {
role = aws_iam_role.execution.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole"
}
resource "aws_iam_role_policy_attachment" "ecs_task" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceEventsRole"
role = aws_iam_role.execution.name
}
resource "aws_iam_role" "execution" {
name = var.fleet_config.iam.execution.name
description = "The execution role for Fleet in ECS"
assume_role_policy = data.aws_iam_policy_document.assume_events.json
}

View File

@ -0,0 +1,181 @@
locals {
environment = [for k, v in var.fleet_config.extra_environment_variables : {
name = k
value = v
}]
secrets = [for k, v in var.fleet_config.extra_secrets : {
name = k
valueFrom = v
}]
}
data "aws_region" "current" {}
resource "aws_cloudwatch_log_group" "main" { #tfsec:ignore:aws-cloudwatch-log-group-customer-key:exp:2022-07-01
count = var.fleet_config.awslogs.create == true ? 1 : 0
name = var.fleet_config.awslogs.name
retention_in_days = var.fleet_config.awslogs.retention
}
resource "aws_ecs_task_definition" "vuln-data-stream" {
family = var.fleet_config.family
cpu = var.fleet_config.vuln_data_stream_cpu
memory = var.fleet_config.vuln_data_stream_mem
execution_role_arn = aws_iam_role.execution.arn
task_role_arn = aws_iam_role.main.arn
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
container_definitions = jsonencode([
{
name = "fleet-vuln-provisioner"
image = var.fleet_config.image
essential = true
user = "root"
command = ["fleetctl", "vulnerability-data-stream", "--dir=${var.fleet_config.vuln_database_path}"]
networkMode = "awsvpc"
mountPoints = [
{
sourceVolume = "efs-mount"
containerPath = var.fleet_config.vuln_database_path
readOnly = false
}
],
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = var.fleet_config.awslogs.create == true ? aws_cloudwatch_log_group.main[0].name : var.fleet_config.awslogs.name
awslogs-region = var.fleet_config.awslogs.create == true ? data.aws_region.current.name : var.fleet_config.awslogs.region
awslogs-stream-prefix = "${var.fleet_config.awslogs.prefix}-data-stream"
}
}
}
])
volume {
name = "efs-mount"
efs_volume_configuration {
file_system_id = aws_efs_file_system.vuln.id
root_directory = var.efs_root_directory
}
}
}
resource "aws_ecs_task_definition" "vuln-processing" {
family = var.fleet_config.family
cpu = var.fleet_config.vuln_processing_cpu
memory = var.fleet_config.vuln_processing_mem
execution_role_arn = aws_iam_role.execution.arn
task_role_arn = aws_iam_role.main.arn
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
container_definitions = jsonencode([
{
name = "fleet-vuln-processing"
image = var.fleet_config.image
essential = true
command = ["fleet", "vuln_processing"]
user = "root"
networkMode = "awsvpc"
mountPoints = [
{
sourceVolume = "efs-mount"
containerPath = var.fleet_config.vuln_database_path
readOnly = false
}
],
secrets = concat(
[
{
name = "FLEET_MYSQL_PASSWORD"
valueFrom = var.fleet_config.database.password_secret_arn
}
], local.secrets),
environment = concat(
[
{
name = "FLEET_MYSQL_USERNAME"
value = var.fleet_config.database.user
},
{
name = "FLEET_MYSQL_DATABASE"
value = var.fleet_config.database.database
},
{
name = "FLEET_MYSQL_ADDRESS"
value = var.fleet_config.database.address
},
{
name = "FLEET_VULNERABILITIES_DISABLE_DATA_SYNC"
value = "true"
},
{
name = "FLEET_VULNERABILITIES_DATABASES_PATH"
value = var.fleet_config.vuln_database_path
}
], local.environment),
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = var.fleet_config.awslogs.create == true ? aws_cloudwatch_log_group.main[0].name : var.fleet_config.awslogs.name
awslogs-region = var.fleet_config.awslogs.create == true ? data.aws_region.current.name : var.fleet_config.awslogs.region
awslogs-stream-prefix = "${var.fleet_config.awslogs.prefix}-procssing"
}
}
}
])
volume {
name = "efs-mount"
efs_volume_configuration {
file_system_id = aws_efs_file_system.vuln.id
root_directory = var.efs_root_directory
}
}
}
resource "aws_cloudwatch_event_rule" "vuln_processing" {
name_prefix = "${var.customer_prefix}-vuln-processing"
schedule_expression = var.fleet_config.vuln_processing_schedule_expression
}
resource "aws_cloudwatch_event_target" "vuln_processing" {
arn = var.ecs_cluster
rule = aws_cloudwatch_event_rule.vuln_processing.name
role_arn = aws_iam_role.run_cloudwatch.arn
ecs_target {
task_definition_arn = aws_ecs_task_definition.vuln-processing.arn
task_count = 1
launch_type = "FARGATE"
network_configuration {
assign_public_ip = false
subnets = var.fleet_config.networking.subnets
security_groups = var.fleet_config.networking.security_groups
}
}
}
resource "aws_cloudwatch_event_rule" "vuln_data_stream" {
name_prefix = "${var.customer_prefix}-vuln-data-stream"
schedule_expression = var.fleet_config.vuln_data_stream_schedule_expression
}
resource "aws_cloudwatch_event_target" "vuln_data_stream" {
arn = var.ecs_cluster
rule = aws_cloudwatch_event_rule.vuln_data_stream.name
role_arn = aws_iam_role.run_cloudwatch.arn
ecs_target {
task_definition_arn = aws_ecs_task_definition.vuln-data-stream.arn
task_count = 1
launch_type = "FARGATE"
network_configuration {
assign_public_ip = false
subnets = var.fleet_config.networking.subnets
security_groups = var.fleet_config.networking.security_groups
}
}
}

View File

@ -0,0 +1,9 @@
output "fleet_extra_environment_variables" {
value = {
FLEET_VULNERABILITIES_DISABLE_SCHEDULE = "true"
}
}
output "enable_dns_hostnames" {
value = true
}

View File

@ -0,0 +1,128 @@
variable "customer_prefix" {
type = string
description = "customer prefix to use to namespace all resources"
default = "fleet"
}
variable "ecs_cluster" {
type = string
description = "The ARN of the ECS cluster to use"
nullable = false
}
variable "vpc_id" {
type = string
default = null
}
variable "fleet_config" {
type = object({
vuln_processing_schedule_expression = optional(string, "rate(1 hour)")
vuln_data_stream_schedule_expression = optional(string, "rate(24 hours)")
vuln_database_path = optional(string, "/home/fleet/vuln_data")
vuln_processing_mem = optional(number, 4096)
vuln_processing_cpu = optional(number, 2048)
vuln_data_stream_mem = optional(number, 1024)
vuln_data_stream_cpu = optinal(number, 512)
image = optional(string, "fleetdm/fleet:v4.28.1")
family = optional(string, "fleet-vuln-processing")
sidecars = optional(list(any), [])
extra_environment_variables = optional(map(string), {})
extra_iam_policies = optional(list(string), [])
extra_execution_iam_policies = optional(list(string), [])
extra_secrets = optional(map(string), {})
iam_role_arn = optional(string, null)
database = object({
password_secret_arn = string
user = string
database = string
address = string
rr_address = optional(string, null)
})
awslogs = optional(object({
name = optional(string, null)
region = optional(string, null)
create = optional(bool, true)
prefix = optional(string, "fleet-vuln")
retention = optional(number, 5)
}), {
name = null
region = null
prefix = "fleet"
retention = 5
})
networking = object({
subnets = list(string)
security_groups = optional(list(string), null)
})
iam = optional(object({
role = optional(object({
name = optional(string, "fleet-vuln-processing-role")
policy_name = optional(string, "fleet-vuln-processing-iam-policy")
}), {
name = "fleet-vuln-processing-role"
policy_name = "fleet-vuln-processing-iam-policy"
})
execution = optional(object({
name = optional(string, "fleet-vuln-processing-execution-role")
policy_name = optional(string, "fleet-vuln-processing-execution-role")
}), {
name = "fleet-vuln-processing-execution-role"
policy_name = "fleet-vuln-processing-iam-policy-execution"
})
}), {
name = "fleet-vuln-processing-execution-role"
})
})
default = {
vuln_processing_schedule_expression = "rate(1 hour)"
vuln_data_stream_schedule_expression = "rate(24 hours)"
vuln_database_path = "/home/fleet/vuln_data"
vuln_processing_mem = 4096
vuln_processing_cpu = 2048
vuln_data_stream_mem = 1024
vuln_data_stream_cpu = 512
image = "fleetdm/fleet:v4.28.1"
family = "fleet-vuln-processing"
sidecars = []
extra_environment_variables = {}
extra_iam_policies = []
extra_execution_iam_policies = []
extra_secrets = {}
iam_role_arn = null
database = {
password_secret_arn = null
user = null
database = null
address = null
rr_address = null
}
awslogs = {
name = null
region = null
create = true
prefix = "fleet-vuln"
retention = 5
}
networking = {
subnets = null
security_groups = null
}
iam = {
role = {
name = "fleet-vuln-processing-role"
policy_name = "fleet-vuln-processing-iam-policy"
}
execution = {
name = "fleet-vuln-processing-execution-role"
policy_name = "fleet-vuln-processing-iam-policy-execution"
}
}
}
description = "The configuration object for Fleet itself. Fields that default to null will have their respective resources created if not specified."
nullable = false
}
variable "efs_root_directory" {
default = "/"
}

View File

@ -2,6 +2,10 @@ output "byo-ecs" {
value = module.ecs value = module.ecs
} }
output "cluster" {
value = module.cluster
}
output "alb" { output "alb" {
value = module.alb value = module.alb
} }

View File

@ -9,3 +9,7 @@ output "rds" {
output "redis" { output "redis" {
value = module.redis value = module.redis
} }
output "secrets" {
value = module.secrets-manager-1
}

View File

@ -22,9 +22,10 @@ module "main" {
certificate_arn = module.acm.acm_certificate_arn certificate_arn = module.acm.acm_certificate_arn
vpc = { vpc = {
name = random_pet.main.id name = random_pet.main.id
enable_dns_hostnames = module.vulnprocessing.enable_dns_hostnames
} }
fleet_config = { fleet_config = {
extra_environment_variables = module.firehose-logging.fleet_extra_environment_variables extra_environment_variables = concat(module.firehose-logging.fleet_extra_environment_variables, module.vulnprocessing.fleet_extra_environment_variables)
extra_iam_policies = module.firehose-logging.fleet_extra_iam_policies extra_iam_policies = module.firehose-logging.fleet_extra_iam_policies
} }
} }
@ -65,3 +66,30 @@ module "firehose-logging" {
name = "${random_pet.main.id}-status" name = "${random_pet.main.id}-status"
} }
} }
module "vulnprocessing" {
source = "../addons/vuln-processing"
customer_prefix = "fleet"
ecs_cluster = module.main.byo-vpc.byo-db.byo-ecs.cluster.cluster_arn
vpc_id = module.main.vpc.vpc_id
fleet_config = {
image = "fleetdm/fleet:v4.28.1"
database = {
password_secret_arn = module.main.byo-vpc.secrets.secret_arns["${var.rds_config.name}-database-password"]
user = module.main.byo-vpc.rds.db_instance_username
address = "${module.main.byo-vpc.rds.db_instance_endpoint}:${module.main.byo-vpc.rds.db_instance_port}"
database = module.main.byo-vpc.rds.db_instance_name
}
extra_environment_variables = {
FLEET_LOGGING_DEBUG = "true"
FLEET_LOGGING_JSON = "true"
}
extra_secrets = {
// FLEET_LICENSE_KEY: "secret_manager_license_key_arn" // note needed for some feature of vuln processing
}
networking = {
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
}
}
}

View File

@ -25,6 +25,8 @@ module "vpc" {
flow_log_cloudwatch_log_group_name_prefix = var.vpc.flow_log_cloudwatch_log_group_name_prefix flow_log_cloudwatch_log_group_name_prefix = var.vpc.flow_log_cloudwatch_log_group_name_prefix
flow_log_cloudwatch_log_group_name_suffix = var.vpc.flow_log_cloudwatch_log_group_name_suffix flow_log_cloudwatch_log_group_name_suffix = var.vpc.flow_log_cloudwatch_log_group_name_suffix
vpc_flow_log_tags = var.vpc.vpc_flow_log_tags vpc_flow_log_tags = var.vpc.vpc_flow_log_tags
enable_dns_hostnames = var.vpc.enable_dns_hostnames
enable_dns_support = var.vpc.enable_dns_support
} }
module "byo-vpc" { module "byo-vpc" {

View File

@ -1,3 +1,7 @@
output "byo-vpc" { output "byo-vpc" {
value = module.byo-vpc value = module.byo-vpc
} }
output "vpc" {
value = module.vpc
}

View File

@ -16,7 +16,8 @@ variable "vpc" {
one_nat_gateway_per_az = optional(bool, false) one_nat_gateway_per_az = optional(bool, false)
single_nat_gateway = optional(bool, true) single_nat_gateway = optional(bool, true)
enable_nat_gateway = optional(bool, true) enable_nat_gateway = optional(bool, true)
enable_dns_hostnames = optional(bool, false)
enable_dns_support = optional(bool, true)
enable_flow_log = optional(bool, false) enable_flow_log = optional(bool, false)
create_flow_log_cloudwatch_log_group = optional(bool, false) create_flow_log_cloudwatch_log_group = optional(bool, false)
create_flow_log_cloudwatch_iam_role = optional(bool, false) create_flow_log_cloudwatch_iam_role = optional(bool, false)
@ -42,7 +43,8 @@ variable "vpc" {
one_nat_gateway_per_az = false one_nat_gateway_per_az = false
single_nat_gateway = true single_nat_gateway = true
enable_nat_gateway = true enable_nat_gateway = true
enable_dns_hostnames = false
enable_dns_support = true
enable_flow_log = false enable_flow_log = false
create_flow_log_cloudwatch_log_group = false create_flow_log_cloudwatch_log_group = false
create_flow_log_cloudwatch_iam_role = false create_flow_log_cloudwatch_iam_role = false