Skip to content

Cloud (DIY): Terraform

Use a published Terraform module from the argusdspm/deploy-argus repo to provision the agent as part of your own Terraform stack, instead of clicking through the AWS console.

There are two, and they are alternatives - pick one. Everything on this page is split into a section per module, so read only the one you chose.

Fargate module EC2 module
Module argus-agent-fargate argus-agent-ec2
Compute Serverless tasks One always-on instance
Autoscaling Optional baseline + burst pool None - a fixed single agent
Best for Estates whose scan backlog varies Smaller estates; simpler and cheaper
Equivalent console path Cloud managed: Fargate Cloud managed: EC2

Both read the region from the configured AWS provider, need no ECR authentication, and create their own IAM roles, secrets, log groups and security groups. The Fargate module is the default recommendation; the EC2 module is the single-host alternative.

Common to both: complete Pre-flight first, have Terraform 1.5+, and have an enrollment token.


argus-agent-fargate provisions the same infrastructure as the Cloud (managed) Fargate template, but inside your own stack.

  • Terraform is already how your team manages AWS infrastructure.
  • You want the agent deploy reviewed via your normal pull request flow instead of the AWS console.
  • You want the option of the argus-agent-baseline + autoscaled argus-agent-burst two-service shape (set enable_burst_autoscaling = true; off by default, same as the managed template).
  • You want to pin the deploy to a specific module ref for reproducibility.
  • Complete Pre-flight first.
  • Terraform 1.5 or newer installed locally.
  • The AWS provider configured for the region you want the agent in (provider "aws" { region = "us-east-2" }). The module reads the region from the provider via data.aws_region.current, so you do not pass it as a module variable.
  • The same VPC and subnet IDs as the Cloud (managed) Fargate path. A public subnet works with assign_public_ip = true; a private subnet with NAT works with the default assign_public_ip = false.
  • An enrollment token.

You do not need to pre-create IAM roles, secrets, log groups, or security groups. The module creates them all.

  1. In a fresh directory, create a providers.tf:

    providers.tf
    terraform {
    required_version = ">= 1.5"
    required_providers {
    aws = { source = "hashicorp/aws", version = "~> 5.0" }
    }
    }
    provider "aws" {
    region = "us-east-2"
    }
  2. Create a main.tf:

    main.tf
    module "argus_agent" {
    source = "github.com/argusdspm/deploy-argus//modules/argus-agent-fargate?ref=v0.9.1"
    customer_name = "production"
    enrollment_token = var.enrollment_token
    vpc_id = "vpc-xxxxxxxxxxxxxxxxx"
    subnet_ids = ["subnet-xxxxxxxxxxxxxxxxx"]
    argus_backend_url = "https://api.argusdspm.com"
    # true for public-subnet deploys (no NAT). Leave false for private
    # subnets that reach the internet via NAT.
    assign_public_ip = true
    # Default-off scanning is the baseline. Flip on per-service or
    # enable_all_datastores = true for first-deploy validation.
    enable_all_datastores = true
    }
    variable "enrollment_token" {
    type = string
    sensitive = true
    }
  3. Initialize and apply:

    Terminal window
    terraform init
    terraform apply -var enrollment_token="argus_et_<your-token-here>"

    The first apply provisions about 25 resources (cluster, two services, two task definitions, IAM roles and policies, security group, Secrets Manager secret, log group, autoscaling pair). Expect 2-3 minutes.

Required:

Variable Type Notes
customer_name string Names and tags every resource. Alphanumerics and hyphens only.
enrollment_token string Bootstrap token. Mark sensitive = true in your declaration.
vpc_id string VPC where the agent runs.
subnet_ids list(string) Subnets in that VPC. One is enough for first deploy; the module spreads tasks across whatever you list.

Commonly tuned:

Variable Default Notes
argus_backend_url https://api.argusdspm.com Override only for self-hosted Argus.
agent_image_tag stable Pin to a specific release tag for reproducibility (the deploy drawer’s version selector lists current releases).
aws_region (provider region) Optional override. By default reads from the configured provider.
assign_public_ip false Set true in public-subnet deploys without a NAT gateway.
enable_all_datastores false true scans S3 + RDS + DynamoDB + Redshift. Or set per-service flags (enable_s3_scanning, etc.).
cpu, memory 1024, 2048 Fargate task sizing.
enable_burst_autoscaling false Provision the autoscaled burst pool. Off by default (baseline-only, matching the managed template); set true to add the burst service + autoscaler. The burst_* variables below apply only when this is on.
burst_min_capacity, burst_max_capacity 0, 10 Bounds for the burst service autoscaler. The baseline service is always 1.
burst_scale_out_backlog 20 Add a burst task when the total unclaimed scan backlog stays at or above this for one minute. The editable scale-out trigger.
burst_scale_in_backlog 5 Remove a burst task when the backlog stays below this for three minutes. Keep below burst_scale_out_backlog to avoid flapping.

The full variable surface is documented in the module’s README at https://github.com/argusdspm/deploy-argus/tree/main/modules/argus-agent-fargate.

Terminal window
terraform output # cluster_name, task_role_arn, etc.
aws ecs describe-services \
--cluster argus-agent-<customer_name> \
--services argus-agent-<customer_name>-baseline \
--query 'services[0].[status,runningCount]' --output text
# expect: ACTIVE 1
aws logs tail /ecs/argus-agent-<customer_name> --follow
# expect bootstrap + auth + polling messages identical to Cloud (managed) Fargate

See Verifying connection.

Terminal window
terraform destroy -var enrollment_token="argus_et_<your-token-here>"

Removes all 25 resources cleanly. The Secrets Manager secret is force-deleted with no recovery window, so the same customer_name can be reused immediately.


argus-agent-ec2 provisions a single EC2 instance running the agent as a Docker container under systemd, pulling the public ghcr.io/argusdspm/argus-agent:stable image. Use it instead of the Fargate module above, not alongside it.

  • You want one always-on instance: simpler and cheaper than Fargate.
  • Your scan backlog is steady, so autoscaling buys you nothing. There is no burst pool - it is a fixed single agent that does not scale with backlog.
  • Your team is more comfortable operating EC2 than ECS.

As in Which module, plus outbound internet from the instance to reach Argus and pull the image: either a public subnet (the module attaches an Elastic IP) or a private subnet with a NAT gateway.

main.tf
module "argus_agent" {
source = "github.com/argusdspm/deploy-argus//modules/argus-agent-ec2?ref=v0.9.1"
customer_name = "production"
enrollment_token = var.enrollment_token
argus_backend_url = "https://api.argusdspm.com"
vpc_id = "vpc-xxxxxxxxxxxxxxxxx"
subnet_id = "subnet-xxxxxxxxxxxxxxxxx"
instance_type = "t3.small"
enable_all_datastores = true
}

Then terraform init and terraform apply -var enrollment_token="argus_et_<your-token-here>", as for Fargate.

Variable Default Notes
instance_type t3.small Instance sizing.
agent_container_image :stable Pin to a specific tag for reproducibility (the deploy drawer’s version selector lists current releases).
aws_region (provider region) Optional override, same as the Fargate module.
enable_all_datastores false true scans S3 + RDS + DynamoDB + Redshift.
enable_iam_discovery false Same flag as the Fargate module.
enable_remediation false Same flag as the Fargate module. Grants the remediation write policy.

The full variable surface is in the module README at https://github.com/argusdspm/deploy-argus/tree/main/modules/argus-agent-ec2.

Terminal window
aws ec2 describe-instances \
--filters "Name=tag:Name,Values=argus-agent-<customer_name>" \
--query 'Reservations[].Instances[].[State.Name,PublicIpAddress]' --output text
# expect: running

Or watch the deploy drawer’s Deployment progress strip. See Verifying connection.

Terminal window
terraform destroy -var enrollment_token="argus_et_<your-token-here>"