CloudLens Autopilot
Verified on real AWS

CloudLens Autopilot for AWS

Deploy CloudLens sensors to your EC2 instances in 5 to 10 minutes (small deployments) or 30 to 60 minutes (thousands of instances). A full 3-component stack (vController + KVO + vPB) was launched live in AWS us-east-1 and reached CREATE_COMPLETE. Linux, Windows, and agentless AWS VPC Traffic Mirroring, fully automated. The mirror session was verified end to end: tapped workload traffic reached the tool, confirmed packet by packet.

📄 Read the end-to-end runbook (PDF)  ·  stack creation to a proven, packet-verified mirror, with the full architecture, every object, and the live evidence.

Ubuntu 20/22/24 RHEL 7/8/9 Windows 2019/2022 3/3 verified

Launch Stack creates the CloudFormation stack only (the vController, KVO and vPB appliances plus networking). For the full automated pipeline that also licenses, adopts, installs sensors, and builds the packet-verified AWS mirror, use Run in CloudShell.

deploy-stack.sh
Don't have vController, KVO, or vPB yet?

Deploy them from AWS Marketplace in one click before running sensor deployments.

Every Launch button below deploys the same CloudLens version in your chosen region. Subscribe to the Marketplace AMIs in that region first.

⚡ Deploy the full CloudLens Stack (recommended)

One CloudFormation stack. Provisions vController + KVO + vPB into a shared VPC with purpose-built mgmt, data, and tool subnets. About 15 minutes from click to ready.

  • One shared VPC with mgmt / data / tool subnets
  • vController + KVO + vPB deployed together, each with its own Elastic IP
  • Instance types constrained to what each Marketplace AMI permits: vController t3.xlarge or m5.xlarge, KVO c5.2xlarge, vPB t3.xlarge
  • Code: CloudFormation template · Terraform stack module · deploy-stack.sh
▶ Launch CloudLens Stack

Or deploy each product separately:

CloudLens vController formerly CLMS

Central management for sensors. Required for any sensor deployment.

  • Version from the Marketplace AMI (CLMS_6.12.x)
  • One instance, t3.xlarge, ready in about 15 minutes
  • Access: web UI over HTTPS (appliance shell uses password auth, not your key pair)
  • Code: Terraform module · CloudFormation template
  • Web UI: https://<vcontroller-ip>
  • UI login: admin / Cl0udLens@dm!n (change on first login)
▶ Launch vController

Vision Orchestrator (KVO) NEW

Optional. Centralizes the vPB fleet and automates AWS VPC Traffic Mirroring.

  • Version from the Marketplace AMI (KVO 2.13.x)
  • One instance, c5.2xlarge (Marketplace-fixed)
  • SSH: ssh -p 9022 admin@<kvo-ip> (port 9022, not 22)
  • Code: Terraform module · CloudFormation template
  • Web UI: https://<kvo-ip>
  • UI login: admin / admin (change on first login)
▶ Launch KVO

Virtual Packet Broker (vPB)

Optional. For inline traffic processing and VXLAN aggregation.

  • Version from the Marketplace AMI (vPB-KVO 3.13.x)
  • One instance, t3.xlarge, multi-ENI layout
  • SSH: ssh -p 9022 admin@<vpb-ip> (NOT port 22)
  • Bootstrap runs automatically at first boot (EC2 user data): kubeconfig + sudo vpb ready on first SSH
  • Code: Terraform module · CloudFormation template
  • CLI access: sudo vpb (works the moment you SSH in)
▶ Launch vPB

After vController finishes initializing (about 15 minutes), open the UI, create a project, copy the project key, then return here to run the sensor deployment.

Prefer Terraform?

vController, KVO, and vPB are all available as Terraform modules in deploy/terraform. The stack module composes all three; the per-component modules deploy them individually: clms (vController), kvo, vpb. Same Marketplace AMIs, IaC-friendly for pipelines and repeatable deployments. The CloudFormation equivalents live in deploy/cloudformation.

cd deploy/terraform/stack
terraform init
terraform apply -var key_name=my-keypair -var deploy_kvo=true -var deploy_vpb=true
Fitting it into the customer's environment

Every Launch button and the CLI take the same options. Leave them alone for a clean lab build, or set them to drop CloudLens into infrastructure the customer already runs.

🏢 Deploy into an existing VPC (brownfield)

Name a VPC and subnet and the stack creates no networking at all: no VPC, no subnets, no internet gateway, no routes. The instances land beside the workloads they monitor.

  • ExistingVpcId + ExistingSubnetId — required together
  • ExistingDataSubnetId — optional, puts the vPB data plane in its own subnet
  • ExistingSecurityGroupId — optional, attaches a pre-approved SG instead of creating one. AdminIngressCidr is then ignored.

Leave ExistingVpcId blank and the four CIDR fields build a fresh VPC instead. That single field is the greenfield / brownfield switch.

curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/deploy-stack.sh | bash -s -- \
  --existing-vpc-id vpc-0abc123 \
  --existing-subnet-id subnet-0def456 \
  --existing-sg-id sg-0aaa111

🩹 Four commands, no stress: check, deploy, replay, remove

For anyone, SE or customer. The doctor finds every setup gap first and prints the exact fix; the deploy asks all of its questions before anything is built and saves your answers; the teardown removes only what it built.

# 1. Is this machine and account ready? Deploys nothing.
curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/deploy-stack.sh | bash -s -- --doctor --region us-east-1

# 2. Deploy. Every question comes first, then one Proceed.
curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/deploy-stack.sh | bash

# 3. Replay a saved deployment anywhere, zero questions (an SE fills the
#    interview once; deploy-profile-<stack>.env is written at the plan step):
curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/deploy-stack.sh | bash -s -- --profile ./deploy-profile-acme.env

# 4. Remove everything it created, when you are done. Audits first, asks before
#    deleting. If the stack has a KVO it offers to release its licences first
#    (or do it in the KVO: Settings > Product Licensing > Deactivate licenses).
curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/teardown-stack.sh | bash -s -- --stack-name YOUR-STACK --region us-east-1

Every run ends with deploy-report-<stack>-<region>.html: what was built, where to sign in, what is tapped, how each phase ended, how to verify, and the exact teardown command. Passwords stay in the mode-600 files it points to, never in the page. Profiles never contain secrets either: licence codes and keys are always typed at the moment of use.

🎯 Tap the customer's workloads, wherever they are

Both tapping paths resolve one selection from customer_input.yaml: ANDed tag_filters, explicit instance_ids, and tapping.exclude_instance_ids drive sensors and agentless mirroring identically, so the two can never target different hosts. The run reports the split up front: which hosts get sensors, which interfaces get mirror sessions (AWS mirrors Nitro instances only), and how many licence credits that demands.

  • --tapping sensors|mirror|both|none — one answer for both paths
  • --source-vpc-id vpc-... — tap a VPC other than the CloudLens one; repeat it (or list aws.source_vpc_ids in customer_input.yaml) and one KVO fabric is built per VPC
  • --source-vpc vpc:az:mgmt:ingress:egress — same, with that VPC's collector placement inline (three distinct subnets in the tapped VPC)
  • --eks-cluster NAME / --eks-sample — tap Kubernetes pods in EKS. Pod-to-pod traffic inside a node is invisible to VM sensors and VPC mirroring; the CloudLens K8s sensor sees it. DaemonSet (one sensor per node, fully automated: image pushed to ECR, applied with kubectl, no helm needed) or sidecar (per-pod; your apps get a rendered snippet, never an automatic restart). --eks-sample builds a small test cluster plus a demo app generating continuous pod-to-pod HTTP. K8s sensors register into the same project as the VM sensors and follow the same tool path.

A tapped VPC that is not the CloudLens VPC needs a route to the manager and KVO on 443 and to the tool from the collector egress subnet (VPC peering or Transit Gateway); the run states exactly that when it applies.

curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/deploy-stack.sh | bash -s -- \
  --tapping both \
  --source-vpc-id vpc-0workloads1 \
  --collector-zone us-east-1a \
  --collector-mgmt-subnet subnet-aaa --collector-ingress-subnet subnet-bbb --collector-egress-subnet subnet-ccc

🔒 Private subnets and no public IPs

Many enterprises forbid Elastic IPs on workload subnets. Set AssignPublicIp to no (or pass --no-public-ip) and no EIPs are created. The stack outputs private IPs and you reach the UIs over VPN, Direct Connect, or VPC peering.

The subnet still needs outbound internet. A NAT gateway or VPC endpoints are required so the Marketplace AMIs can activate and the vPB first-boot bootstrap can run. With no egress the instances launch but never finish initializing, and the stack still reports success.

🔑 SSH key pair: use an existing one or have it created

A brand new AWS account has no key pairs, which used to block the wizard entirely. Now you choose:

  • Create a new key pair for me (default) — the stack creates <StackName>-key, EC2 stores the private key in SSM Parameter Store, and the stack outputs the exact command to download it
  • Use an existing key pair — type the name in KeyPairName

The CLI lists the key pairs in your region and lets you pick one or create a new one. In the console it is a text box rather than a dropdown, because CloudFormation cannot make a key pair dropdown optional: a dropdown must always resolve to an existing key, which is exactly what blocks a first deploy.

# Download the auto-created private key (the stack prints this command)
aws ssm get-parameter --name /ec2/keypair/<key-pair-id> --region <region> \
  --with-decryption --query Parameter.Value --output text > my-key.pem && chmod 400 my-key.pem
What happens after you click Create

CloudFormation builds in dependency order, so resources appear in waves rather than all at once. Timings below are from a real deploy of vController plus three test VMs in us-east-1. Watch it live on the Events tab, or the Timeline view for a Gantt chart.

  1. 0:00
    Stack accepted

    Status goes CREATE_IN_PROGRESS. Nothing exists yet.

  2. 0:18
    Network foundation

    VPC, then the internet gateway and its attachment. Skipped entirely if you supplied an existing VPC.

  3. 0:23
    Subnets and routing

    The mgmt, data, and tool subnets appear together, then their route table associations. Also the security groups.

  4. 0:39
    Elastic IP pre-check

    A short Lambda confirms the account has enough Elastic IPs for this stack. This is the gate: if it fails, the stack stops here with a message naming the shortfall and no instance is ever launched. See Common issues.

  5. 0:43
    Instances launch

    vController, then KVO and vPB if selected, plus any test workloads. They start in parallel, so this is one wave rather than three.

  6. 0:57
    Elastic IPs attached

    Addresses were allocated earlier; here they are associated with the running instances.

  7. 1:07
    CREATE_COMPLETE

    Infrastructure is done. Read the Outputs tab for UI URLs, SSH commands, and the test VM addresses.

CREATE_COMPLETE is not "ready to log in". CloudFormation finishes when the EC2 instances are running, but the CloudLens appliances are still booting. Allow roughly 15 minutes before the vController UI responds, and about 5 minutes before vPB accepts SSH on port 9022. A full stack with KVO and vPB takes longer to reach CREATE_COMPLETE than the single-component timing above.

If the stack rolls back, open the Events tab and sort oldest first: the first CREATE_FAILED row is the real cause, everything after it is cleanup.

One command, full stack

vController, KVO, and vPB plus sensors. End to end. From a single paste.

curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/deploy-stack.sh | bash

Prompts for region and key pair, accepts Marketplace terms, deploys vController, waits for initialization, optionally adds KVO and vPB, then chains to sensor deployment. Run from AWS CloudShell or any machine with the AWS CLI.

Bash (recommended)

One paste, end to end. Best for: trying it the first time, or onboarding a new customer.

Terraform Stack Module

Single command, vController plus KVO and vPB. Best for: IaC pipelines and repeatable infra.

cd deploy/terraform && terraform init && terraform apply \
  -var key_name=my-keypair -var deploy_kvo=true -var deploy_vpb=true

Browse the Terraform code on GitHub →

Printable Runbook

Executive-friendly PDF guide. Best for: customer CTO, procurement, training.

Download Runbook

One command back down

Same discipline in reverse. It removes what this deployment created, and nothing else.

1. See what is loose first. Read-only, deletes nothing: the stack, what it left behind, and what that is costing. Put your stack name and region in.

curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/teardown-stack.sh | bash -s -- --stack-name YOUR-STACK --region YOUR-REGION --orphans

2. Tear it down. Audits again, shows what it found, and asks you to confirm before deleting. If the stack has a KVO, the script then lists the licences it holds and offers to release them before anything is deleted (default yes on a terminal; --release-licences answers it without one): they come back while the KVO is alive and never afterwards, and the teardown is confirmed first so licences are only stripped from a KVO you have already chosen to destroy. Only a release that leaves the KVO clear skips the licence-loss confirmation; anything else is explained and the typed stack name is still required. The UI route remains: release them yourself first under Settings > Product Licensing > Deactivate licenses, then run the teardown.

curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/teardown-stack.sh | bash -s -- --stack-name YOUR-STACK --region YOUR-REGION

Deleting the CloudFormation stack on its own is not enough, and that surprises people. The Marketplace AMIs set DeleteOnTermination=false, so on any stack launched before 15 September 2026 the root volumes survive as available and keep billing; the templates now override that, and this script sweeps such volumes either way. KVO creates the collector Auto Scaling group and its security groups outside CloudFormation, so the stack cannot see them, and a VPC still holding them cannot be deleted. CloudFormation can then report DELETE_COMPLETE and still leave the whole network standing. This script deletes the stack and sweeps the volumes, security groups, scaling groups and launch templates it can attribute to it. If the VPC itself outlives the stack, run --orphans afterwards to see what is still standing, and remove the VPC by hand.

It only removes what your deployment built. Nothing is deleted unless AWS itself ties it to your stack, by stack membership, by living in the VPC that stack created, or by an owner tag naming it. Anything without that evidence is reported and left alone, because in a shared account "it was unattached" is not proof of ownership. Brownfield deploys into an existing VPC (--existing-vpc-id) switch the VPC rule off entirely: that network is the customer's, and its other contents are none of the script's business. Stack name and region are yours to pass, so the same command is safe in any account.

Add --orphans to audit without deleting, --dry-run to print every command it would run, or --sweep-only to clean up after a stack that is already gone. Nothing is removed without an explicit confirmation, or --yes in a pipeline.

Verify it end-to-end on disposable VMs

For SE demos or first-call verification: stand up 3 throwaway workload EC2 instances (Ubuntu 22.04 + RHEL 9 + Windows Server 2022) tagged with a discovery tag, then run the stack with the matching tag flags. Proves sensors install on every supported OS in one pass.

# 1. Stand up the 3 test workload instances (default tag: cloudlens=yes)
curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/scripts/deploy-test-workload-vms.sh | bash

# 2. Deploy the CloudLens stack, then run sensor deployment against the tagged instances
curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/deploy-stack.sh | bash

# 3. Cleanup when done
aws cloudformation delete-stack --stack-name cloudlens-test-vms --region us-east-1

The fixture launches three instances tagged cloudlens=yes with an os tag per platform. The sensor deployment installs on all three and they register with vController. Total round trip: about 25 to 30 minutes. Override the tag pair with TESTVMS_TAG_KEY / TESTVMS_TAG_VALUE environment variables if you want to mirror a customer's existing convention.

Run from Docker

Pinned image with Ansible, the AWS SDKs, and pywinrm. Works from your laptop, a CI runner, or any container host.

docker run --rm -it \
  -v $(pwd)/customer_input.yaml:/work/customer_input.yaml \
  -v $HOME/.ssh:/root/.ssh:ro \
  -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY \
  -e AWS_DEFAULT_REGION \
  ghcr.io/keysight-tech/cloudlens-ansible-aws:latest

AWS credentials are passed via environment variables (use scripts/setup_aws_creds.sh to configure a profile). Same behavior as the CloudShell quickstart, just packaged for CI/CD or repeat customer deployments.

Image registry

Image is published to GitHub Container Registry on every push to main: ghcr.io/keysight-tech/cloudlens-ansible-aws.

View on ghcr.io

Build locally

Prefer to build your own image instead of pulling? The Dockerfile is in the repo root.

git clone https://github.com/Keysight-Tech/cloudlens-ansible-aws.git
cd cloudlens-ansible-aws
docker build -t cloudlens-ansible-aws .

CI/CD pattern

Drop the same docker run into GitHub Actions, GitLab CI, Jenkins, or CodeBuild. Mount your customer_input.yaml as a build artifact.

Watch it deploy

Pick a path and run it, the fabric diagram wires itself up as each step completes, with the plain-English narration and the raw output alongside. This is a live visualization of the real sequences; the actual deploy runs in your CloudShell.

Prefer it full-screen? Open the full console →

Get started in 5 steps

Most deployments under 50 instances complete in 5 to 10 minutes.

  1. Check prerequisites 2 minutes

    You need these in place before deploying:

    • AWS account with EC2 and CloudFormation permissions in your target region
    • CloudLens vController (formerly CLMS) deployed and reachable from your target instances
    • A project key from vController (Settings, Projects, API Keys)
    • An EC2 key pair (for SSH targets) or SSM enabled (for Windows targets)

    If you do not have vController deployed yet, use the Launch vController button above.

  2. Tag your EC2 instances 5 minutes

    The deployment discovers instances by tag. Apply these to every target instance:

    TagValue
    cloudlensyes
    osubuntu or rhel or windows
    envprod (or dev, qa)

    Tag a single instance:

    aws ec2 create-tags --resources i-0123456789abcdef0 \
      --tags Key=cloudlens,Value=yes Key=os,Value=ubuntu Key=env,Value=prod
  3. Build your config file 1 minute

    Use the wizard below to fill the fields and download customer_input.yaml.

    Jump to wizard ↓

    Tip: the wizard shows the YAML rendering live as you type. Each field has inline help so you know exactly what to enter.

  4. Deploy 5 to 60 minutes

    Place your downloaded customer_input.yaml in your working directory, then pick one of the three deploy paths.

    Tier 1: CloudFormation

    One click. No local tools. Best for: trying it for the first time.

    Launch Stack

    Tier 2: CloudShell

    Already authenticated. One curl command. Best for: most customers.

    curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/quickstart.sh | bash

    Tier 3: Docker

    Reproducible. Pinned versions. Best for: CI or repeat deployments.

    docker run --rm -it -v $(pwd)/customer_input.yaml:/work/customer_input.yaml ghcr.io/keysight-tech/cloudlens-ansible-aws:latest
  5. Verify in vController 2 minutes

    Open your vController web UI and confirm:

    • Each tagged instance appears as a registered sensor (under Sensors)
    • Custom tags from your config match what you see in vController
    • Sensors show as connected and reporting

    Stuck? See the troubleshooting section below or the full troubleshooting docs.

Build your customer_input.yaml

Fill in four fields. Download the file. Run quickstart. That is the whole flow.

1

CloudLens vController

Where do I find this?

The IP or hostname of your vController deployment. You can find it in the AWS console under the vController EC2 instance details, or in the Outputs of your CloudFormation stack.

2

Project key

Where do I find this?

In the vController web UI: Settings, Projects, API Keys, copy the key for the project you want sensors to register under.

3

Custom tags

What does this do?

These tags are attached to each registered sensor and visible in vController. Use them to filter and group sensors (for example: Customer=Acme, Region=us-east-1). Space-separated key=value pairs.

4

Regions

What goes here?

The AWS regions the deployment scans for tagged EC2 instances. List one or more, comma-separated. Defaults to us-east-1.

Live architecture flow

A single Ansible control point authenticates to AWS, discovers EC2 instances by tag, and routes each host to the right OS lane. The CloudLens sensor on each EC2 instance mirrors traffic (mirror / VXLAN) to the vPB, which forwards to your monitoring tool. Every sensor self registers with vController on first start.

Flow: CloudLens sensor on EC2 to mirror / VXLAN to vPB to monitoring tool. The dotted line shows sensor registration traffic back to vController.

How does it scale?

Drag the slider to see the estimated deployment time for your fleet size.

Instances 100
Forks 50
Sharded No
Estimated time 15 to 30 min
1 to 505 to 10 min
50 to 50015 to 30 min
500 to 2,00030 to 60 min
2,000 to 10,00030 to 60 min (sharded)
10,000+1 to 2 hr (AWX)
Verified against real AWS

A full 3-component stack was launched via CloudFormation in us-east-1 and reached CREATE_COMPLETE, then the full pipeline was proven end to end: KVO licensing, vController and vPB adoption, 3-OS sensor registration, and agentless AWS mirror sessions.

3 / 3 Stack components live vController, KVO, vPB
CREATE_
COMPLETE
CloudFormation status Region us-east-1
3 AMIs Correct Marketplace AMIs t3.xlarge / c5.2xlarge / t3.xlarge
End to end Pipeline proven Licensing, adoption, sensors, mirroring
ComponentResultInstance type
CloudLens vController (control plane)CREATE_COMPLETEt3.xlarge
Vision Orchestrator (KVO)CREATE_COMPLETEc5.2xlarge
Virtual Packet Broker (vPB)CREATE_COMPLETEt3.xlarge
Full stack (stack.yaml)3/3 live in us-east-1Shared VPC
vController configuration (one-time)

Once CloudFormation or Terraform finishes, configure the Keysight products via their web UIs. One-time setup, about 15 minutes end to end. vController was formerly named CLMS.

1

Accept the KVO EULA

KVO blocks all access, including the API, until the EULA is accepted in the browser. Open https://<kvo-ip>, read the Keysight Software EULA, click Agree, then log in with admin / admin.

This must be done in the browser. The CLI cannot accept the EULA on your behalf.
2

Activate licenses on KVO

Navigate to Settings, Product Licensing, Activate. Three licenses must be enabled: vPB Advanced, CloudLens Enterprise, and KVO perpetual. If the license server is unreachable, copy the offline activation key from your Keysight portal.

3

Adopt vController and provision the key

From KVO: Inventory, CloudLens Manager, Discover. Enter the vController private IP and the admin credentials (admin / Cl0udLens@dm!n), and commit the change request KVO raises. Status must turn CONNECTED.

Then create the Cloud Config, Visibility Fabric, Cloud Configs, New, Custom Cloud. This provisions the real project on the vController and returns the sensor key; skip it and the key is a phantom that won't register sensors.

4

Adopt the vPB into KVO

SSH to the vPB on port 9022 (not 22). The kvo command is an interactive context, not flat commands, run sudo vpb and enter it:

CloudLensVPB# kvo
CloudLensVPB-kvo# ip <kvo-private-ip>
CloudLensVPB-kvo# port 443
CloudLensVPB-kvo# enable      # prints "KVO enabled"
CloudLensVPB-kvo# exit
Running kvo ip <x> / kvo enable as flat commands does not enable KVO. You must enter the context first.

The vPB self-announces and appears under Inventory, Devices, Auto Discovery within ~30 s. Adopt it with Control the adopted device enabled, KVO consumes a device license, the vPB is auto-licensed, comes up Online, and KVO auto-creates its Device Config.

5

Wire the vPB traffic path

Bind the Device Config ports and connect the fabric so the vPB collects, filters, and forwards to a tool:

  • eth1 (ingress) → a Cloud-to-Device Link (L2GRE), which sets the receiving IP on the vPB.
  • eth2 (egress) → a Tool (your analyzer / NPB).
  • A Monitoring Policy ties source → vPB → tool.

A tapping vPB needs 3 NICs (mgmt / ingress / egress), the stack wires these automatically when Zone Tapping is enabled.

Preparing existing customer VMs

Skip this if you used the disposable test fixture, those instances are already configured. Deploying sensors to existing customer EC2 instances? Prep them with the included script in scan-then-fix mode.

IAM role

Auto-fix: Yes

Each instance needs AmazonSSMManagedInstanceCore attached to its instance profile. The prep script creates a CloudLens-SSM-Role and attaches it for you. If the instance already has an IAM role, the script adds the SSM policy to it instead of replacing.

SSM Agent

Auto-fix: Mostly

Pre-installed on Amazon Linux, Ubuntu 16.04+, Windows Server 2016+. Must be installed manually on RHEL/CentOS, commands below.

Tags

Auto-fix: Yes

The script auto-detects each instance OS and applies cloudlens=yes plus the correct os tag (ubuntu, rhel, or windows).

Step 1 - Scan your environment first

Run scan-only mode to see what is missing before changing anything:

./scripts/deploy.sh --region us-east-1 --profile customer --scan-only

Step 2 - Auto-fix every issue

Once you have reviewed the scan, run with --auto-fix to remediate every gap in one shot:

./scripts/deploy.sh --region us-east-1 --profile customer --auto-fix

Omit --auto-fix for interactive mode, the script prompts before each change.

Step 3 - Manual SSM Agent install (when Instance Connect is not available)

Ubuntu / Debian

sudo snap install amazon-ssm-agent --classic
sudo systemctl enable snap.amazon-ssm-agent.amazon-ssm-agent.service
sudo systemctl start snap.amazon-ssm-agent.amazon-ssm-agent.service

RHEL / CentOS

sudo dnf install -y \
  https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
sudo systemctl enable amazon-ssm-agent
sudo systemctl start amazon-ssm-agent

Windows (PowerShell admin)

# SSM Agent is pre-installed on Windows Server 2016+
# If it is not responding, restart it:
Restart-Service AmazonSSMAgent
After installing SSM Agent, wait 30 to 60 seconds for it to register with AWS Systems Manager. Verify with: aws ssm describe-instance-information --region us-east-1
Sensor deployment via Ansible

Push CloudLens sensors to every tagged EC2 instance at fleet scale over SSH, SSM, or WinRM, with outbound HTTPS from each instance back to vController.

Tag targets first

Apply the marker tag cloudlens = yes and an os tag to every target instance. Without these the deployment skips the host.

OSTag os
Ubuntu / Debianubuntu
RHEL / CentOS / Amazon Linuxrhel
Windows Server 2016+windows

IAM role on every target

Each instance needs the managed policy AmazonSSMManagedInstanceCore attached to its instance profile for the SSM connection path. The included prep step can attach this for you and verify the SSM Agent is running.

SSM Agent reachability

Each instance must reach ssm.<region>.amazonaws.com, ec2messages.<region>.amazonaws.com, and ssmmessages.<region>.amazonaws.com on 443 outbound, or have a VPC endpoint to those services.

Run the deployment

# Deploy to ALL tagged targets in the region
bash quickstart.sh

# Or run the playbook directly with your customer_input.yaml
ansible-playbook deploy.yaml -e @customer_input.yaml

The playbook invokes the CloudLens sensor installer on every matching instance in parallel, Docker or Podman on Linux, MSI on Windows. Sensors register with vController on first start.

Agentless AWS mirroring

No sensor in the guest. KVO deploys collector Service VMs and drives AWS VPC Traffic Mirroring, AWS copies traffic from every selected Nitro source ENI to the collectors, which forward it to your tool. Real AWS resources: mirror targets, filters, and one session per source ENI.

1

Give KVO AWS permissions

Mirroring is KVO calling AWS on your behalf, so it needs credentials. Enable the opt-in, least-privilege Zone-Tapping policy (deploy/iam/cloudlens-zonetap-policy.json): greenfield with EnableZoneTapping=yes (CloudFormation) or enable_zone_tapping="true" (Terraform), brownfield with scripts/kvo_enable_zonetap_iam.sh.

Left off, the base suite still deploys with no IAM required, important where the deploying principal can't create IAM roles.
2

Sources must be Nitro

AWS VPC Traffic Mirroring only taps Nitro instances, CloudLens inherits this AWS limit. t3 / m5 / c5 / r5 and newer are Nitro (confirm with describe-instance-types … Hypervisor). Non-Nitro hosts can't be tapped, put sensors on those. Sources are selected by the cloudlens=yes tag, the same tag the sensor path uses.

3

Create a Cloud Config and a tool

On KVO: Cloud Fabric, Cloud Configs, New, AWS. Supply the region and source VPC, the collector image (auto-resolved per region), the SSH key and mgmt / ingress / egress subnets, then commit, KVO deploys an auto-scaling group of collector Service VMs. Under Visibility Fabric, Tools create the destination tool (Local or Remote) the mirrored traffic is forwarded to.

4

Monitoring policy → sessions

In KVO: Monitoring Policies, New, pick the source (the cloudlens=yes cloud collection) and the tool. KVO creates the Traffic Mirror target and filter, then one session per source ENI. Confirm with aws ec2 describe-traffic-mirror-sessions or under VPC, Traffic Mirroring.

Mix and match, mirror the Nitro hosts agentlessly and put sensors on the rest, both land under the same vController / KVO project.

Teardown

Clean removal of sensors and infrastructure. Always run in this order, sensors first, infrastructure second.

Step 1 - Remove sensors

# Remove sensors from all tagged targets
bash cleanup.yaml

# Or via the playbook
ansible-playbook cleanup.yaml -e @customer_input.yaml

Step 2 - Destroy infrastructure

Terraform path:

cd deploy/terraform
terraform destroy

CloudFormation path, use the teardown script rather than a bare delete-stack:

bash deploy/teardown-stack.sh \
  --stack-name cloudlens-stack \
  --region us-east-1

A bare delete-stack leaves the appliance root volumes billing, leaves the collector Auto Scaling group rebuilding itself, and can report DELETE_COMPLETE while the VPC is still standing. The script handles all three and verifies the result. See One command back down.

Appendix - reference

Default credentials, network topology, and Marketplace AMIs. Keep this open in a tab during deployment.

Key facts that bite

ItemWhat to know
vPB kvoAn interactive context, enter kvo, then ip / port 443 / enable / exit. Flat commands don't enable it.
vPB licenseAuto-applied on adoption from KVO's device licenses, no manual license server.
AWS mirroringNitro sources only (t3 / m5 / c5 / r5+). Non-Nitro, use sensors.
Source tagcloudlens=yes drives both the sensor and the mirror paths.
Key ports443 vController / KVO API · 9022 vPB SSH · 8443 KVO↔collector.
After CREATE_COMPLETEAppliances need ~15 min to initialize before the UI accepts a login.

Default credentials

ProductUsernamePassword
KVOadminadmin
vControlleradminCl0udLens@dm!n
vPB SSH (port 9022)ec2-userkey pair

Change these on first login. Default passwords are not for production.

Network topology

SubnetCIDRPurpose
Management10.0.1.0/24SSH, HTTPS, REST API
Data10.0.2.0/24Sensor traffic (mirror / VXLAN)
Tool10.0.3.0/24Processed traffic to tools

CIDRs are configurable in the CloudFormation parameters.

Marketplace AMIs and instance types

ProductInstance
vController (CLMS_6.12.x)t3.xlarge
KVO (2.13.x)c5.2xlarge only
vPB-KVO (3.13.x)t3.xlarge

KVO has an AWS Marketplace instance-type restriction and cannot be changed.

Common issues

If something does not work, check these first.

My deploy stopped partway. Do I have to start over?

No. A run can stop for ordinary reasons: Ansible is not installed yet, there is nothing tagged to put a sensor on, an SSO token expires, a laptop sleeps. None of that loses the infrastructure already built.

Re-run the same command with --resume. It checks the real system rather than a state file: CloudFormation for the stack, the vController API, the KVO licensing API. Everything already finished is skipped and it picks up at the first unfinished step, usually in about a minute.

curl -sSL https://raw.githubusercontent.com/Keysight-Tech/cloudlens-ansible-aws/main/deploy/deploy-stack.sh | bash -s -- \
  --region us-east-1 --stack-name cloudlens-stack --resume

Related: --fresh runs every phase again and skips nothing; --from PHASE starts at a named phase (stack, wait, key, license, adopt, sensors, vpb, path, mirror); --only PHASE runs exactly one.

Nothing in the deploy script deletes anything, including under --fresh. Teardown is a separate, explicitly confirmed command.

Stack rolled back: "The maximum number of addresses has been reached"

You are out of Elastic IPs. The default quota is 5 per region, and the full stack needs 3 (one each for vController, KVO, and vPB). If the account already holds EIPs, the deploy runs for several minutes, allocates what it can, then fails on the last one and rolls the whole stack back.

The usual cause is orphaned EIPs: terminating a stack's instances from the EC2 console leaves the CloudFormation stack, and its Elastic IPs, in place. They bill hourly while attached to nothing, and they block the next deploy.

List anything unattached:

aws ec2 describe-addresses --region us-east-1 \
  --query 'Addresses[?AssociationId==`null`].[PublicIp,AllocationId,Tags[?Key==`Name`]|[0].Value]' \
  --output table

If they belong to a stack whose instances are already gone, delete the stack so it does not simply recreate them:

aws cloudformation delete-stack --stack-name <name> --region us-east-1

Otherwise release them directly:

aws ec2 describe-addresses --region us-east-1 \
  --query 'Addresses[?AssociationId==`null`].AllocationId' --output text \
  | tr '\t' '\n' | xargs -I{} aws ec2 release-address --region us-east-1 --allocation-id {}

Alternatives: request a quota increase, or deploy with no public IPs at all using --no-public-ip (see Deployment options) and reach the stack over VPN, Direct Connect, or peering.

deploy-stack.sh now checks this before deploying and tells you which addresses to free, so you get the message in seconds instead of after a rollback.

I don't have vController (formerly CLMS) yet. Where do I start?

Use the Launch vController button at the top of this page, or launch the full stack with the Launch CloudLens Stack button above. vController comes from AWS Marketplace, deploys in about 15 minutes, and is ready before you start tagging your instances. While you are there, also deploy KVO if you want centralized fleet orchestration across multiple vPB instances.

vPB just deployed. Why can't I SSH yet?

The vPB image uses port 9022 for SSH, NOT the default port 22. Keysight CloudLens OS (KCOS) binds sshd only to 9022 on the public interface. Connections to :22 time out forever even after the instance is fully booted.

What to do: wait 10 to 15 minutes after deploy succeeds for KCOS to initialize, then:

ssh -p 9022 admin@<vpb-public-ip>   # OS shell
sudo vpb                                # vPB CLI

Security group rule: make sure the security group on the vPB management ENI allows inbound TCP on port 9022. The stack template opens this automatically; if you deployed via a custom path, add the rule manually.

Same vController note: the web UI on port 443 is usually ready within 60 seconds, but full system initialization (registry and project creation) takes around 15 minutes.

Inventory finds 0 instances

Cause: tags missing or misspelled.

Fix: verify with aws ec2 describe-tags --filters "Name=resource-id,Values=i-0123...". The cloudlens, os, and env tags must all be present.

SSH Permission denied

Cause: your key pair is not on the target instance, or the wrong SSH user.

Fix: use ubuntu for Ubuntu and ec2-user for RHEL/Amazon Linux, and confirm ssh_key_path in customer_input.yaml points at the right .pem. For no-key targets, use the SSM connection path instead.

WinRM or SSM timeout on Windows instances

Cause: for the SSM path, the SSM Agent is not registered or the instance lacks the SSM IAM role; for the WinRM path, ports 5985/5986 are closed.

Fix: prefer windows_connection: "ssm", attach AmazonSSMManagedInstanceCore, and confirm the instance appears in aws ssm describe-instance-information.

Sensor does not appear in vController

Cause: wrong project key, or sensor cannot reach vController on the network.

Fix: double-check the project key from the vController UI. Verify the instance can reach vController on port 443.

How long should this take?

1 to 50 instances: 5 to 10 minutes.

50 to 500 instances: 15 to 30 minutes.

500 to 2000 instances: 30 to 60 minutes.

Thousands: sharded automatically, 30 to 60 minutes for up to 10K.

What if I need help?

Open an issue on GitHub, or contact your Keysight account team for direct engineering support.