Kaizen

OpenObserve

Self hosted logs, metrics, and traces on Fargate behind an internal FIPS TLS ALB.

GovCloudFIPSCMKView source
Module
openobserve
Layer
Observability
Interface
39 inputs, 8 outputs
Used by
No apps yet

Why it matters

Teams need to search logs and traces without shipping data to a third party service that a federal customer has not approved. This module runs OpenObserve inside the VPC, stores telemetry in an S3 bucket the account owns, and ships with FIPS TLS, vendor telemetry turned off, and 90 day log retention.

Use it when

  • A federal or air gapped deployment needs log search that stays inside the account.
  • You want to route app logs through Fluent Bit with ecs-service's main_container_log_configuration.

Reach for something else when

  • CloudWatch Logs from ecs-service is enough. It needs no extra infrastructure. Use ecs-service.
  • You want browser side performance and error data. Use rum.

What it creates

  • aws_ecs_task_definition and aws_ecs_service (OpenObserve plus a NATS coordinator)
  • aws_lb, aws_lb_target_group, and HTTPS and HTTP redirect listeners (internal by default)
  • aws_security_group (load balancer and task) with rules
  • aws_s3_bucket for telemetry (versioning, encryption, public access block, lifecycle)
  • aws_iam_role (task and execution, partition aware policy ARN)
  • aws_cloudwatch_log_group (encrypted with the required kms_key_arn)
  • aws_route53_record (A record in a private hosted zone)

Secure by default

  • The load balancer is internal (alb_internal = true) and uses ELBSecurityPolicy-TLS13-1-2-FIPS-2023-04.
  • The log group requires a customer managed key (kms_key_arn has no default).
  • OpenObserve telemetry to the vendor is off (telemetry_enabled = false).
  • The image is pinned to a release tag, never latest.
  • Logs and telemetry are kept for 90 days, and the telemetry bucket refuses force deletion.

Commercial and GovCloud

main.tf
module "openobserve" {
  source = "git::ssh://git@github.com/the-kaizen-labs/terraform-modules.git//openobserve?ref=v1.7.0"

  name_prefix        = local.app_name
  vpc_id             = module.networking.vpc_id
  private_subnet_ids = module.networking.private_subnet_ids
  alb_subnet_ids     = module.networking.private_subnet_ids
  ecs_cluster_id     = module.ecs_cluster.cluster_id
  kms_key_arn        = aws_kms_key.this.arn
  certificate_arn    = local.certificate_arn

  private_hosted_zone_id = local.private_zone_id
  parent_domain          = "internal.example.com"

  metadata_postgres_dsn_ssm_arn = aws_ssm_parameter.o2_meta_db_dsn.arn
  admin_email                   = "devops@example.com"
  admin_password_ssm_arn        = local.o2_admin_password_arn

  caller_ingress_security_group_ids = [module.ecs_service.security_group_id]

  tags = local.tags
}
SettingCommercial defaultFederal settingNote
ssl_policyELBSecurityPolicy-TLS13-1-2-FIPS-2023-04ELBSecurityPolicy-TLS13-1-2-FIPS-2023-04FIPS 140-3 TLS is the default here.
s3_kms_key_arnnull (AES256)customer managed KMS key ARNFedRAMP SC-13 and SC-28.
log_retention_days9090 or moreFedRAMP AU-11.
s3_endpoint_urlnull (https://s3.<region>.amazonaws.com)https://s3-fips.<region>.amazonaws.com in commercial FedRAMP, the partition endpoint in GovCloud
telemetry_enabledfalsefalse

How it connects

  • From networking: vpc_id, private_subnet_ids
  • From ecs-cluster: cluster_id (as ecs_cluster_id)
  • From rds-postgres: db_host, in the SSM DSN passed as metadata_postgres_dsn_ssm_arn
  • From ecs-service: security_group_id (as caller_ingress_security_group_ids)
  • To ecs-service: ingest_host, for Fluent Bit log routing
  • To rds-postgres: task_security_group_id (as allowed_security_group_ids)

Inputs

NameTypeDefaultRequiredDescription
admin_emailstringyesInitial OpenObserve root user email.
admin_password_ssm_arnstringyesSSM SecureString ARN holding the OpenObserve root user password. Caller creates this out-of-band.
alb_subnet_idslist(string)yesSubnets for the ALB.
certificate_arnstringyesACM certificate ARN covering the OpenObserve host.
ecs_cluster_idstringyesECS cluster ID.
kms_key_arnstringyesCMK ARN for CloudWatch logs and Secrets Manager secrets.
metadata_postgres_dsn_ssm_arnstringyesSSM SecureString ARN holding the full Postgres DSN for OpenObserve metadata. Caller manages the RDS instance and SSM parameter.
name_prefixstringyesResource name prefix. Used for every resource name and as the DNS label.
parent_domainstringyesParent domain. Full DNS record defaults to <name_prefix>-o2.<parent_domain> unless hostname overrides it.
private_hosted_zone_idstringyesRoute53 private hosted zone ID for the internal A-record.
private_subnet_idslist(string)yesPrivate subnets for the OpenObserve Fargate task.
vpc_idstringyesVPC ID.
alb_internalbooltruenoIf true, the ALB is internal-only. Set false for dev envs without VPN access.
allowed_ingress_cidrslist(string)[]noCIDRs allowed to reach the ALB on 443.
caller_ingress_security_group_idslist(string)[]noSecurity groups allowed to reach the ALB on 443 (e.g. app task SGs for firelens).
cpu_architecturestring"ARM64"noTask CPU architecture (X86_64 or ARM64).
desired_countnumber1noECS service desired_count. Default 1 (single-node OO). For an HA cluster set this >=3 alongside nats_replicas.
hostnamestringnullnoOptional full FQDN for the OpenObserve UI/ingest endpoint. When null (default), the module composes <name_prefix>-o2.<parent_domain>. Set to override the -o2 suffix when you want a custom hostname like obs.example.com. Must still be under parent_domain (the Route53 record is created in the zone passed via private_hosted_zone_id).
imagestring"public.ecr.aws/zinclabs/openobserve:v0.80.3"noOpenObserve container image.
keycloak_oidc_client_idstringnullnoKeycloak OIDC client_id.
keycloak_oidc_client_secret_ssm_arnstringnullnoSSM ARN holding the OIDC client secret.
keycloak_oidc_enabledboolfalsenoToggle OpenObserve Enterprise + Dex-backed Keycloak SSO.
keycloak_oidc_group_attributestring"groups"noOIDC claim carrying groups -> OpenObserve teams.
keycloak_oidc_issuerstringnullnoKeycloak realm issuer URL.
keycloak_oidc_role_attributestring"roles"noOIDC claim carrying roles -> OpenObserve roles.
keycloak_oidc_scopesstring"openid profile email groups"noOIDC scopes (space-delimited).
log_retention_daysnumber90noCloudWatch log retention. FedRAMP AU-11 requires >=90.
nats_imagestring"public.ecr.aws/docker/library/nats:2.10-alpine"noNATS image used as OpenObserve's cluster coordinator.
nats_replicasnumber1noZO_NATS_REPLICAS. Default 1 (single-node OO). For an HA cluster set this >=3 alongside desired_count.
platform_versionstring"1.4.0"noFargate platform version.
s3_endpoint_urlstringnullnoOverride for ZO_S3_SERVER_URL. When null (default), the module composes 'https://s3.&#60;region&#62;.amazonaws.com' (commercial AWS, non-FIPS). For FedRAMP commercial pass 'https://s3-fips.&#60;region&#62;.amazonaws.com'; for GovCloud pass the partition-appropriate endpoint.
s3_force_destroyboolfalsenoIf true, terraform destroy auto-empties the telemetry bucket (versions + delete markers + current objects) before deleting it. Default false (federal-safe). Set true for dev/POC envs where you genuinely want to nuke the bucket without leaving an orphan.
s3_kms_key_arnstringnullnoOptional CMK ARN for telemetry bucket SSE. When null (default), the bucket uses AES256. Set for FedRAMP/GovCloud (SC-13/SC-28). Note: flipping this on an existing bucket only encrypts new objects; existing AES256 objects are not rewritten.
s3_retention_daysnumber90noTelemetry retention in S3 before lifecycle expiration.
ssl_policystring"ELBSecurityPolicy-TLS13-1-2-FIPS-2023-04"noALB SSL policy. Defaults to FIPS 140-3 TLS 1.3.
tagsmap(string){}noTags applied to all resources.
task_cpustring"1024"noTask-level CPU units.
task_memorystring"2048"noTask-level memory in MiB.
telemetry_enabledboolfalsenoZO_TELEMETRY. Default false. OO phones home to ZincObserve when true, which is a non-starter for federal/air-gapped deployments. Flip to true only for commercial dev envs where you want to help upstream.

Outputs

NameDescription
alb_dns_nameDNS name of the ALB.
alb_security_group_idSG attached to the ALB.
alb_zone_idRoute53 hosted zone ID of the ALB.
ingest_hostHostname for OTLP / firelens ingest. Same host as the UI.
otlp_http_endpointOTLP HTTP ingest endpoint (same host as the UI; routed by path).
s3_bucketTelemetry bucket.
task_security_group_idSG attached to the OpenObserve task.
ui_urlInternal UI URL.

Used by

No Kaizen app uses this module yet.

On this page