Deploy Terraform using CLI

Qualys provides Terraform modules for deploying the cloud scanning infrastructure for AWS Lambda function scanning and Fargate inventory collection. This approach is an alternative to the CloudFormation-based deployment and is suited for teams managing AWS infrastructure as code.

The deployment consists of two modules: a service account module that hosts the core scanning infrastructure, and a target account module deployed once per AWS account you want to scan. Deploy the service account module first, then the target account module for each target account.

For full variable details and advanced configuration, see TERRAFORM_DEPLOYMENT_GUIDE.md included in the Terraform package.

Pre-requisites

Before you begin, make sure you have the following items ready for Cloud Scanning Infrastructure.

  1. AWS account
    1. Designated for the Qualys Service Account scanning infrastructure. 
    2. From your AWS account, the ServiceAccountId where you want to deploy the Service Account stack. 
    3. From your AWS account, the TargetAccountId or OrganizationId where you want to deploy the Target Account stack. That is, the target account of the lambda functions that you want to scan.
      Either TargetAccountId or OrganizationId must be supplied to the service account stack before any cross-account target can send events.
  2. Qualys Serverless Scanning Terraform package
    Download the package using the following command.
    curl -L -o cs-cloud-deployment-templates-terraform-1.0.0-0.zip \ 
    https://raw.githubusercontent.com/Qualys/Qualys-serverless-scanning-deployment/main/terraform/cs-cloud-deployment-templates-terraform-1.0.0-0.zip
  3. Environment details for your Qualys subscription:
    1. Qualys Cloud Operator Image from Dockerhub.
      Refer to How to Get the Qualys Cloud Operator Image?
    2. Authorization: You can either use an Access Token or ClientID and SecretID for the authorization.
      ClientID, SecretID
      OR
      Qualys Enterprise TruRisk™ Platform > Container Security > Configurations > Access Token
      Doc References: 
      - CS 1.43 Release Notes > Development Environment Scanning with QScanner
      - API Authentication using Qualys Managed Tokens
      OR
      A Secrets Manager ARN holding ClientID and SecretID, and/or Access Token.
    3. (Optional for AWS Lambda Scan) To scan your Fargate inventory, get your Qualys CustomerID from any pre-populated sensor installation command.
      Qualys Enterprise TruRisk™ Platform > Container Security > Configurations > Sensors > Install Sensor > Installation Instructions
    4. Gateway URL: Qualys Enterprise TruRisk™ Platform (POD) gateway URL for communication.
    5. Optional parameter, proxy, VPC if required.

Step 1: Deploy the Service Account Module

The service account module deploys the core scanning infrastructure: the cloud-operator Lambda function, SQS queues, DynamoDB tables, and EventBridge rules. Deploy this module first, in the AWS account designated as your service account.

  1. Navigate to the service account examples directory.

    cd terraform/aws/service-account/examples/complete

  2. Copy the example variables file.

    cp terraform.tfvars.example terraform.tfvars

  3. Edit terraform.tfvars for your environment. The full set of available variables is shown in the table below.
  4. Deploy the service account stack.
    terraform init
    terraform plan -var-file terraform.tfvars
    terraform apply -var-file terraform.tfvars

The cloud_operator_image_uri architecture must match the cloud_operator_lambda_architecture variable (x86_64 or arm64). A mismatch causes a Runtime.InvalidEntrypoint error.

The table below describes the key variables for the service account module.

Variable Mandatory Default Description
primary_region Yes — AWS region for the service account stack deployment.
aws_profile No ambient AWS CLI profile for the service account. Set explicitly to avoid applying to the wrong account.
cloud_operator_image_uri Yes — Container image URI for the cloud-operator Lambda function. Must be in the same region as the stack.
cloud_operator_lambda_architecture No x86_64 Lambda architecture: x86_64 or arm64. Must match the image architecture.
gateway_url Yes — Qualys platform gateway URL for your POD.
qualys_access_token No* — Qualys access token for authentication. Use instead of OAuth credentials.
qualys_client_id + qualys_client_secret No* — Qualys OAuth client ID and secret. Use as an alternative to qualys_access_token.
qualys_secret_arn No* — AWS Secrets Manager ARN holding Qualys credentials. Use instead of plaintext token or OAuth values.
organization_id No** — AWS Organizations ID. Authorizes all accounts in the organization to onboard as target accounts without requiring stack updates for each new account.
target_account_ids No** [] Explicit list of target AWS account IDs. Use instead of organization_id for individual account targeting. Requires a stack update for each new target account.
scan_service_account No true When true, scans Lambda functions in the service account itself in addition to any target accounts.
enable_lambda_scanning No true Enables Lambda function scanning on the service account stack.
enable_fargate_inventory No true Enables Fargate inventory collection on the service account stack.
customer_id Yes (Fargate) — Qualys Customer ID. Required when enable_fargate_inventory = true.
secondary_regions No [] Additional AWS regions where EventBridge forwarding rules are deployed via CloudFormation StackSet. Do not include the primary region.
enable_cloud_metadata_collection No false Enables task-definition payload and tag enrichment for Fargate workloads.
scan_types No pkg,fileinsight,aiinsight Comma-separated list of scan types to run on Lambda function packages.
log_level No info Log verbosity: debug, info, warn, error, or fatal.
vpc_id, subnet_ids, security_group_ids No — VPC networking for the Lambda function. All three must be set together.

* At least one authorization method is required: qualys_access_token, OAuth credentials (qualys_client_id + qualys_client_secret), or qualys_secret_arn.
** At least one of organization_id or target_account_ids must be set before onboarding target accounts.

Step 2: Deploy the Target Account Module

Repeat this step once per AWS account you want to scan. Each target account deployment sends an automatic onboarding notification to the service account — no manual trigger is needed.

Do not use the same AWS account for both the service account module and the target account module.

  1. Navigate to the target account examples directory.

    $ cd terraform/aws/target-account/examples/complete

  2. Copy the example variables file.

    $ cp terraform.tfvars.example terraform.tfvars

  3. Edit terraform.tfvars for the target account. The full set of available variables is shown in the table below.
  4. Deploy the target account stack.
    $ terraform init
    $ terraform apply -var-file terraform.tfvars

    On successful apply, an onboarding notification is sent automatically to the service account. No manual trigger is needed.

The table below describes the variables for the target account module.

Variable Mandatory Default Description
primary_region Yes — AWS region for the target account stack deployment.
aws_profile No ambient AWS CLI profile for the target account. Set explicitly to avoid applying to the wrong account.
service_account_id Yes — AWS account ID of the service account where the scanning infrastructure is deployed.
service_account_region Yes — AWS region where the service account stack is deployed. Queue and bus ARNs are built from this value.
secondary_regions No [] Additional AWS regions in the target account from which to forward events. Must not include the target stack deploy region.
deployment_name No cloud-scanning-target Name prefix for deployed resources in the target account.
enable_lambda_scanning No true Deploys EventBridge rules to forward Lambda function lifecycle events to the service account.
enable_fargate_inventory No true Deploys EventBridge rules to forward ECS Fargate Task State Change events to the service account.

Step 3: Verify the Deployment

  1. Check that the service account and each target account are registered with status = active.
    aws --profile service-account dynamodb scan --table-name qualys-onboarded-accounts
  2. Tail the cloud-operator Lambda logs to confirm scan activity.
    aws --profile service-account logs tail /aws/lambda/qualys-cloud-operator --follow

Destroy the Stacks

Always run terraform destroy from the same working directory and as the same OS user used during deployment.

Destroy the target account stack first, then the service account stack.

For Target Account,

cd terraform/aws/target-account/examples/complete
terraform destroy -var-file terraform.tfvars

For Service account

cd terraform/aws/service-account/examples/complete
terraform destroy -var-file terraform.tfvars

Destroying a target account stack removes its onboarding record and Lambda scan jobs from the service account DynamoDB tables.