Deployment (AWS Marketplace)
Launch the OBSESC CloudFormation stack in your AWS account: prerequisites, parameter groups, outputs, and post-launch checks.
OBSESC deploys from a single CloudFormation template into a VPC you choose. This page covers the prerequisites, the stack parameters you’re most likely to set, and what to check once the stack is up. For the shortest path, see the Quick start.
Prerequisites
| Requirement | Notes |
|---|---|
| VPC and subnet | The node runs in one subnet (single Availability Zone). It needs outbound access to Amazon S3 and to the AWS APIs it uses (Secrets Manager, SSM Parameter Store and AWS Marketplace Metering when those are configured), through a NAT gateway or VPC endpoints. |
| Customer-managed KMS key | Encrypts the root and data EBS volumes and every S3 object OBSESC writes (SSE-KMS). If you keep EBS snapshots enabled, the key policy must allow the stack’s snapshot (DLM) role to use the key. An IAM grant alone isn’t enough. |
| S3 bucket | Bring an existing bucket, or let the stack create one (CreateRawBucket=true). |
| Instance quota | Enough c6in capacity in the Region for the instance type you choose. |
The AMI is x86_64 and based on Amazon Linux 2023.
Required parameters
| Parameter | Description |
|---|---|
AmiId | The OBSESC AMI ID. |
RawBucketName | The S3 bucket that holds raw events, for example my-obsesc-bucket. |
VpcId | The VPC to deploy into. |
SubnetId | The subnet for the node. |
KmsKeyArn | Your customer-managed key, for example arn:aws:kms:us-east-1:111122223333:key/.... |
Compute and storage
| Parameter | Default | Description |
|---|---|---|
InstanceType | c6in.2xlarge | One of c6in.2xlarge, 4xlarge, 8xlarge, 12xlarge, 16xlarge or 24xlarge. |
WalVolumeSizeGiB | 100 | EBS volume for the write-ahead log (20–16384). |
SummaryVolumeSizeGiB | 500 | EBS volume for the navigation tier (100–16384). Size it for your retention window, because this data accumulates over time. |
AnomalyVolumeSizeGiB | 100 | EBS volume for unusual-behaviour data (20–16384). |
EnableDataVolumeSnapshots | true | Daily snapshots of the data volumes, keeping the last 7. |
All volumes are gp3 and encrypted with KmsKeyArn.
The stock template deploys a single node. Contact us about multi-node deployments.
Raw bucket
By default (CreateRawBucket=false) OBSESC writes to a bucket you already own, and you manage its lifecycle rules. If you use S3 lifecycle transitions, declare them in the node configuration so OBSESC can warn you about early-deletion charges. See What happens next.
With CreateRawBucket=true, the stack creates the bucket with SSE-KMS, public access blocked and DeletionPolicy: Retain. It adds these lifecycle transitions:
| Parameter | Default | Description |
|---|---|---|
StandardIaAfterDays | 30 | Age at which objects move to Standard-IA (minimum 30). |
GlacierIrAfterDays | 180 | Age at which objects move to Glacier Instant Retrieval. Must be at least 30 days after StandardIaAfterDays. |
The stack never uses Glacier Flexible Retrieval or Deep Archive. Every raw object stays retrievable in milliseconds.
The bucket is retained when you delete the stack. If a stack that created a bucket rolls back, the empty bucket stays behind, and a retry with the same name fails. Delete the empty bucket (or switch to bring-your-own) before you retry.
Object Lock (WORM)
Only with CreateRawBucket=true:
| Parameter | Default | Description |
|---|---|---|
EnableObjectLock | false | Creates the bucket with S3 Object Lock and versioning. You can only turn this on when the bucket is created. |
ObjectLockMode | governance | governance lets principals with s3:BypassGovernanceRetention delete. compliance lets nobody delete, including the account root, and can’t be undone for the versions it covers. |
ObjectLockRetainDays | 30 | Default retention applied to each new object version. |
Bucket in another account or Region
| Parameter | Description |
|---|---|
RawBucketAccountId | The 12-digit account that owns a bring-your-own bucket, if it isn’t this account. The RawBucketPolicySnippet output contains the bucket policy to apply in that account. |
S3AssumeRoleArn | A role the node assumes for all raw-bucket calls, as an alternative to a bucket policy. The S3AssumeRoleTrustSnippet output contains the trust statement that role needs. |
S3Region | The bucket’s Region, if it differs from the stack’s Region. Cross-Region traffic incurs inter-Region data transfer charges. |
Network access
| Parameter | Default | Description |
|---|---|---|
AllowedIngestCidr | 10.0.0.0/8 | The source range allowed to reach the node’s ingest ports, the console and the query API. |
The node’s security group allows these TCP ports from AllowedIngestCidr:
| Port | Purpose |
|---|---|
| 4317 | OTLP/gRPC |
| 4318 | OTLP/HTTP (protobuf) |
| 9200 | Elasticsearch _bulk |
| 18080 | Console, query API and the /ready health check |
The node also listens on 24224 (Fluent Forward), 8088 (Splunk HEC) and 9000 (Vector native). The template doesn’t open them. If your shippers use these protocols, add inbound rules to the node’s security group for your shipper ranges. See Network configuration.
Because the console and the query API share port 18080, anyone in AllowedIngestCidr can reach both. Keep the range narrow, set AuthSecretArn, and use the console load balancer below for operator access.
Authentication and TLS
Both are optional, but you should set them for anything beyond an evaluation.
| Parameter | Description |
|---|---|
AuthSecretArn | A Secrets Manager secret holding JSON with any of: query_api_token (string), ingest_tokens (array), hec_tokens (array), fluent_shared_key (string). The node loads it at startup and fails closed if it can’t. Tokens never touch the config file on disk. |
TlsCertSsmParameter | An SSM SecureString parameter holding the PEM certificate chain for the listeners. |
TlsKeySsmParameter | An SSM SecureString parameter holding the matching PEM private key. |
When AuthSecretArn is set, the node also enforces role-based access on its API, and query_api_token acts as an administrator. Include a query_api_token in the secret. If the secret holds only ingest tokens, the node refuses to start rather than reject every API call.
A secret might look like this:
{
"query_api_token": "<generate-a-long-random-value>",
"ingest_tokens": ["<token-for-shippers>"],
"hec_tokens": ["<token-for-splunk-hec-clients>"]
}
Without AuthSecretArn, the listeners and API are unauthenticated, apart from Splunk HEC, which rejects every request until hec_tokens is set. Without the TLS parameters, the listeners serve plain HTTP.
For details, see Security model and Encryption.
Console access and sign-in
The node serves the console on port 18080. With every option below off, you reach it directly at http://<private-ip>:18080/ (or https:// when the TLS parameters are set).
If you set AuthSecretArn and open the console directly, it loads but can’t show data, because nobody is signed in. For operator access, use the load balancer with sign-in through your identity provider.
Internal load balancer
| Parameter | Default | Description |
|---|---|---|
EnableUiLoadBalancer | false | Adds an internal Application Load Balancer in front of the console. Its health check uses /ready, so a node that isn’t ready leaves rotation automatically. |
UiAlbSubnetIds | (empty) | At least two subnets in different Availability Zones, in VpcId. |
UiAllowedCidr | 10.0.0.0/8 | Who can reach the load balancer on ports 80 and 443. |
UiCertificateArn | (empty) | An ACM certificate. With it, the load balancer serves HTTPS on 443 and redirects HTTP. Without it, it serves plain HTTP on 80. |
UiPrivateZoneId, UiHostname | (empty) | A Route 53 private hosted zone and a name in it, for example obsesc.your-domain.internal. Set both together. |
The load balancer reaches the node on port 18080 through a security group rule, not a CIDR range.
Single sign-on with per-user roles
EnableUiPerUserRbac=true puts sign-in through your OIDC identity provider in front of the console. Every user signs in as themselves, and OBSESC gives each user their own role:
- Admin can use the whole console and change settings.
- Viewer can explore, search and investigate, but can’t change anything.
Sign-in requires EnableUiLoadBalancer, UiCertificateArn and AuthSecretArn, plus these parameters:
| Parameter | Description |
|---|---|
UiOidcIssuerUrl, UiOidcClientId | Your identity provider’s issuer URL and the client ID of the OBSESC application. |
AlbOidcAuthorizationEndpoint, AlbOidcTokenEndpoint, AlbOidcUserInfoEndpoint | Your identity provider’s OIDC endpoints. The load balancer needs all three explicitly. |
AlbOidcClientSecret | The OIDC client secret. The load balancer takes the secret itself, not a Secrets Manager ARN. |
AlbOidcSignerPublicKeyPem | The load balancer’s public signing key for your Region. This is a public key, not a secret. |
NodeApiOidcJwksUrl | Recommended. Lets the node pick up the load balancer’s new signing keys automatically. |
NodeApiOidcClaim | Which claim identifies a user: email (the default), sub, username or groups. Use groups only if your identity provider includes it in the user information the load balancer receives. |
NodeApiOidcAdminValue | The claim value that gets the admin role, for example an administrator’s email address or a group name. |
NodeApiOidcViewerValue | The claim value that gets the viewer role. Set it to * so every signed-in user can at least view. Otherwise, users who aren’t mapped are refused. |
The load balancer also needs outbound HTTPS to your identity provider. The stack adds that rule when sign-in is on.
When a sign-in session expires, the console may report that it can’t reach the node. Reload the page to sign in again.
See IAM and permissions and Security model.
Alerting
| Parameter | Default | Description |
|---|---|---|
AlertmanagerEndpoint | (empty) | host:port of an Alertmanager the node can reach, for example alertmanager.your-domain.internal:9093. |
OBSESC ships alert rules that deliver to your Alertmanager. When AlertmanagerEndpoint is empty, those alerts aren’t delivered to anyone. The built-in alerts include an always-firing heartbeat alert. Route it to a dead-man’s-switch receiver so you’ll know if alert delivery itself breaks. See Monitoring.
Evaluation features
| Parameter | Default | Description |
|---|---|---|
EvaluationFeatures | Disabled | Enabled turns on additional console views, custody verification and a sample alert, so those views show data straight away. |
SummaryLevelDimension | level | The attribute the console uses for severity views (log.level for ECS). |
SummaryStatusDimension | error_code | The attribute the console uses for status views (http.response.status_code for ECS). |
SummaryLatencyDimension | latency_ms | The numeric attribute the console uses for latency views (event.duration for ECS). |
The three attribute parameters apply only when evaluation features are enabled.
Custody verification is optional and off by default. When it’s on, you can verify in the console that OBSESC’s records haven’t been altered. It doesn’t cover the raw events in your S3 bucket. See Audit and verification.
Enabling evaluation features adds processing work, so on a busy node some console views may take longer to fill in. Changing this parameter on an existing stack replaces the instance.
Metering
| Parameter | Default | Description |
|---|---|---|
MarketplaceProductCode | (empty) | Supplied through AWS Marketplace. When empty, no usage is reported. |
MarketplaceUsageDimension | (as supplied) | Supplied through AWS Marketplace. Don’t change it unless we ask you to. |
Launch and wait
After you create the stack, the node prepares its data volumes, writes its configuration and starts. The stack waits for the node’s /ready check to succeed. If the node doesn’t become ready, the stack fails. It doesn’t report success with a broken node.
If the stack fails, contact us. The instance role includes Session Manager access, so you can connect to the instance without SSH keys if we ask you to collect logs.
Stack outputs
| Output | Description |
|---|---|
IngestEndpointOtlp | http://<private-ip>:4318/v1/logs |
IngestEndpointEs | http://<private-ip>:9200/_bulk |
UiUrl | The console. With the load balancer, its DNS name or your private DNS name. Without it, http://<private-ip>:18080/ (https:// when the TLS parameters are set). |
QueryApiEndpoint | The query API on port 18080 |
MetricsEndpoint | The node’s Prometheus metrics endpoint on port 18080 |
AlertDelivery | Whether alerts are delivered (DELIVERING to … or NOT DELIVERING …) |
RawBucket | The raw bucket name |
RawBucketPolicySnippet, S3AssumeRoleTrustSnippet | Policies to apply in another account, when relevant |
Post-launch checklist
- Confirm that
curl http://<private-ip>:18080/readyreturns200. - Check the
AlertDeliveryoutput. - Open the console at the
UiUrloutput. - Send a test event and watch it arrive. See Your first logs.
- Decide on a retention window. See What happens next.