Deploy Cloud Formation Template (CFT) using CLI
Use the AWS CLI to deploy the Qualys-provided CloudFormation templates for Serverless Scanning. This topic walks you through deploying the service account stack, adding secondary regions, onboarding target accounts, and verifying the deployment.
Prerequisites
Before you begin, make sure you have the following items ready for Cloud Scanning Infrastructure.
- AWS account
- Designated for the Qualys Service Account scanning infrastructure.
- From your AWS account, the ServiceAccountId where you want to deploy the Service Account stack.
- 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. - AWS CLI configured with credentials for both the service account and target account.
- Qualys CloudFormation templates (CFT)
- CFT for Service account
URL:https://qualys-cs-cloud-scanning-cf-template.s3.amazonaws.com/CS-CLOUD-DEPLOYMENT-TEMPLATES-CFT-2.0.0-0/qualys-cs-service-account-scanning.yaml - CFT for Target account
URL:https://qualys-cs-cloud-scanning-cf-template.s3.amazonaws.com/CS-CLOUD-DEPLOYMENT-TEMPLATES-CFT-2.0.0-0/qualys-cs-target-account-scanning.yaml
- CFT for Service account
- Environment details for your Qualys subscription:
- Qualys Cloud Operator Image from Dockerhub.
Refer to How to Get the Qualys Cloud Operator Image? - 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.
Use the following commands to create a Secret ARN.
1. Run the following command. Replace<>with valid values.cat > qualys-creds.json <<'EOF' { "access_token": "<Qualys access token>", "client_id": "<Qualys client id>", "client_secret": "<Qualys client secret>" } EOF
2. Create AWS Secret ARN.aws secretsmanager create-secret \ --name qualys/credentials \ --description "Qualys credentials for Cloud Operator" \ --secret-string file://qualys-creds.json \ --region <service account region> \ --profile <service account profile>
3. Copy the newly generated secret ARN from the output.{ "ARN": "arn:aws:secretsmanager:<service account region>:<aws account id>:secret:<name>-xxxxxx", "Name": "qualys/credentials", "VersionId": "2e31143b-xxxx-xxxx-xxxx-xxx62569xxxx", "VersionStages": [ "AWSCURRENT" ] }
4. Remove the credential file.rm -f qualys-creds.json - (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 - Gateway URL: Qualys Enterprise TruRisk™ Platform (POD) gateway URL for communication.
- CustomerId (required when enabling Fargate inventory).
- Optional parameter, proxy, VPC if required.
- Qualys Cloud Operator Image from Dockerhub.
Step 1 - Deploy the Service Account Stack
The service account hosts the scanning orchestrators, SQS queues, DynamoDB tables, and EventBridge rules. Deploy the service account CloudFormation stack using the following command.
- Set OrganizationId or TargetAccountIds on the service account stack before onboarding any target account. If neither is set, the target account's onboarding notification will be rejected and the target stack deployment will fail.
- Do not include the primary deployment region in SecondaryRegions. It is added automatically.
aws cloudformation create-stack \
--stack-name qualys-cloud-scanning-service-account \
--template-url https://qualys-cs-cloud-scanning-cf-template.s3.amazonaws.com/CS-CLOUD-DEPLOYMENT-TEMPLATES-CFT-2.0.0-0/qualys-cs-service-account-scanning.yaml \
--parameters \
ParameterKey=CloudOperatorImageUri,ParameterValue=<service account id>.dkr.ecr.<region>.amazonaws.com/cloud-operator:<tag> \
ParameterKey=GatewayURL,ParameterValue=<Qualys Gateway URL> \
ParameterKey=QualysSecretArn,ParameterValue=<Qualys secret ARN> \
ParameterKey=CustomerId,ParameterValue=<customer id> \
ParameterKey=OrganizationId,ParameterValue=<AWS organization id> \
ParameterKey=SecondaryRegions,ParameterValue="<secondary region 1>\,<secondary region 2>" \
--capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND \
--region <service account region> \
--profile <service account profile>
The --profile service-account flag must resolve to credentials for the service account.
The table below describes the key parameters for the service account stack.
| Parameter | Mandatory | Default | Description |
|---|---|---|---|
| CloudOperatorImageUri | Yes | — | ECR image URI for the Qualys Cloud Operator image, in the same region as the stack. |
| GatewayURL | Yes | — | Qualys subscription gateway URL for backend communication. |
| QualysSecretArn | No* | — | AWS Secrets Manager ARN holding Qualys credentials. When provided, secretsmanager:GetSecretValue is scoped to this ARN only. Omit if using plaintext QualysAccessToken or QualysClientId / QualysClientSecret. |
| QualysAccessToken — or — QualysClientId + QualysClientSecret |
No* | — | Plaintext Qualys credentials. Use one of these or QualysSecretArn. At least one authorization method is required. |
| CustomerId | Yes (Fargate) | — | Qualys Customer ID. Required when EnableFargateInventory=true. |
| OrganizationId | No** | — | AWS Organizations ID (recommended). Authorizes all accounts in your organization to send events. No stack update needed when new target accounts onboard. |
| TargetAccountIds | No** | — | Comma-separated explicit list of target account IDs. You must update this parameter and the stack before onboarding each new target account. |
| EnableLambdaScanning | No | true | Set to false to deploy a Fargate-only service account. |
| EnableFargateInventory | No | false | Set to true to enable Fargate inventory collection alongside Lambda scanning. |
| EnableCloudMetadataCollection | No | false | Enables task-definition payload and tag enrichment for Fargate workloads. |
| ScanServiceAccount | No | true | When true, scans Lambda functions in the service account itself in addition to any target accounts. |
| SecondaryRegions | No | — | Comma-separated list of additional AWS regions (excluding the stack deploy region) to deploy EventBridge forwarding rules via StackSet. |
| LogLevel | No | info | Log level for Lambda functions: debug, info, warn, error, or fatal. |
* At least one authorization method is required: either QualysSecretArn or the plaintext credential pair.
** At least one of OrganizationId or TargetAccountIds must be set before onboarding target accounts.
To capture events from additional AWS regions within the service account, update the stack with the SecondaryRegions parameter. A CloudFormation StackSet deploys EventBridge forwarding rules in each listed region.
The secondary-region Fargate rule is only deployed when both ScanServiceAccount=true and EnableFargateInventory=true.
Step 2 - Deploy the Target Account Stack
Once you ensure the Service Account stack is generated, deploy the target account stack.
Using credentials for the target account, deploy the target account CloudFormation template. This creates the QualysCloudOperatorRole cross-account IAM role and EventBridge rules that forward Lambda and Fargate events to the service account.
Do not use the same AWS account for both the service account stack and the target account stack.
aws cloudformation create-stack \ --stack-name qualys-cloud-scanning-target-account \ --template-url https://qualys-cs-cloud-scanning-cf-template.s3.amazonaws.com/CS-CLOUD-DEPLOYMENT-TEMPLATES-CFT-2.0.0-0/qualys-cs-target-account-scanning.yaml \ --parameters \ ParameterKey=ServiceAccountId,ParameterValue=<service account id> \ ParameterKey=ServiceAccountRegion,ParameterValue=<service account region> \ ParameterKey=SecondaryRegions,ParameterValue="<secondary region 1>\,<secondary region 2>" \ --capabilities CAPABILITY_NAMED_IAM \ --region <target account region> \ --profile <target account profile>
The --profile target-account flag must resolve to credentials for the target account, not the service account.
The table below describes the parameters for the target account stack.
| Parameter | Mandatory | Default | Description |
|---|---|---|---|
| ServiceAccountId | Yes | — | AWS account ID of the service account where the Lambda scanning infrastructure is deployed. |
| ServiceAccountRegion | Yes | — | AWS region where the service account stack is deployed. For example, us-west-2. |
| EnableLambdaScanning | No | true | Deploys EventBridge rules to forward Lambda function lifecycle events to the service account. |
| EnableFargateInventory | No | false | Deploys EventBridge rules to forward ECS Fargate Task State Change events to the service account. |
| SecondaryRegions | No | — | Additional AWS regions in the target account from which to forward events. Must not include the target stack deploy region. For example, sa-east-1,eu-west-1. |
When the target account stack is successfully deployed, an onboarding-notifier custom resource automatically sends a registration message to the service account. The service account registers the target account, backfills a scan of all existing Lambda functions, and enqueues an initial Fargate bulk scan.
To capture events from secondary regions within the target account, set the SecondaryRegions parameter on the target account stack. A StackSet deploys forwarding rules in each listed region; events are routed to the service account's EventBridge bus and then to SQS.
Do not include the region where the target stack itself is deployed in SecondaryRegions.
EventBridge cannot target an SQS queue in another region directly. Secondary-region rules use bus-to-bus forwarding: the target-account StackSet sends events to the service account's EventBridge bus, and the service-account rules then route them to the appropriate SQS queues.
Verify the Deployment
After completing the steps above, confirm the deployment is working correctly.
- Confirm the service account stack status is CREATE_COMPLETE or UPDATE_COMPLETE.
- Confirm the target account stack status is CREATE_COMPLETE. A failed onboarding-notifier custom resource means the target account is not authorized on the service account stack — revisit Step 1.
- Check the qualys-onboarded-accounts DynamoDB table for the target account with status = active and all expected regions.
- In the service account, check the CloudWatch log groups /aws/lambda/qualys-cloud-operator and /aws/lambda/qualys-fargate-inventory for the onboarding backfill and incoming events.
- Start or restart a Fargate task in the target account and confirm the event flows through qualys-fargate-inventory-events and appears in the qualys-fargate-inventory logs.
- Confirm the dead-letter queues (DLQs) are empty in the service account: qualys-lambda-events-dlq, qualys-fargate-inventory-events-dlq, qualys-fargate-bulk-scan-dlq, qualys-onboarding-events-dlq, and qualys-fargate-events-rule-dlq.
Destroy the Stacks
Delete the target account stack first, then the service account stack. Deleting a target account stack removes its onboarding record and stops Lambda and Fargate events from that account being processed.
Always delete the target account stack before the service account stack. Deleting the service account stack first leaves orphaned IAM roles and EventBridge rules in the target account.
- Delete each target account stack. Repeat for every onboarded target account.
aws cloudformation delete-stack \ --stack-name qualys-cloud-scanning-target-account \ --region us-west-2 \ --profile target-accountWait for the stack status to reach DELETE_COMPLETE before proceeding.
aws cloudformation wait stack-delete-complete \ --stack-name qualys-cloud-scanning-target-account \ --region us-west-2 \ --profile target-account - Delete the service account stack.
aws cloudformation delete-stack \ --stack-name qualys-cloud-scanning-service-account \ --region us-west-2 \ --profile service-account
If the service account stack deletion fails due to non-empty S3 buckets or DynamoDB tables with deletion protection, empty or disable them manually before retrying.