Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

AWS Systems Manager: Automate Fleet Operations

By Kokil Thapa | Last reviewed: August 2026

Managing dozens of servers via individual SSH connections is a security risk and an operational bottleneck that does not scale. AWS Systems Manager: Automate Fleet Operations solves this by providing a unified interface to configure, patch, and secure your entire infrastructure without opening inbound ports. For teams building scalable and efficient systems, adopting SSM is often the turning point between fragile manual administration and reliable, auditable automation.

How does AWS Systems Manager automate fleet operations securely?

At its core, AWS Systems Manager (SSM) inverts the traditional connectivity model. Instead of you reaching into the server via SSH on port 22, the SSM Agent installed on each instance maintains a persistent, encrypted outbound connection to the AWS service endpoint. This architecture means your instances can reside entirely in private subnets with no public IP addresses and no inbound security group rules required for management.

Private SubnetEC2 Instance ASSM AgentEC2 Instance BSSM AgentOn-Prem ServerSSM AgentAWS CloudSystems ManagerSecure ChannelOperatorConsole / CLIIAM Auth OnlyOutbound TLS OnlyNo Port 22 Needed
AWS Systems Manager architecture: agents initiate secure outbound connections, eliminating inbound SSH access

This shift has profound implications for security posture. In my experience working on production infrastructure for legal-tech portals where data sensitivity is paramount, removing public SSH access reduces the attack surface dramatically. You no longer worry about brute-force attacks on port 22 or managing rotating SSH key pairs across a growing team. Access control shifts entirely to AWS IAM policies, which are far more granular and auditable than Linux user accounts.

The SSM Agent comes pre-installed on Amazon Linux 2023, Ubuntu 22.04/24.04 LTS, and Windows Server 2019+ AMIs. For older instances or hybrid environments, installation is a single command. The agent requires only outbound HTTPS (port 443) access to specific regional SSM endpoints, making it compatible with strict egress-filtered networks. Once registered, the instance appears in the SSM Fleet Manager console within minutes, ready for automated operations.

What are the essential IAM permissions for SSM automation?

Before running any commands, you must configure two distinct IAM roles correctly. Misconfiguring these is the most common reason SSM fails in new deployments. The first role attaches to the EC2 instance itself; the second governs what human operators or CI/CD pipelines can do.

Instance Profile Configuration

Every managed node needs an instance profile with the AmazonSSMManagedInstanceCore managed policy. This grants the minimum permissions for the agent to communicate with the service, send heartbeats, and fetch commands. Avoid attaching administrator policies to instances; this violates least-privilege principles and creates lateral movement risks if an instance is compromised.

<!-- Minimal trust policy for EC2 instance role -->
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "ec2.amazonaws.com" },
      "Action": "sts:AssumeRole"
    }
  ]
}

<!-- Attach AmazonSSMManagedInstanceCore + CloudWatchAgentServerPolicy -->

If your instances run in private subnets without NAT gateways, add VPC endpoints for ssm, ssmmessages, and ec2messages. Without these, the agent cannot reach the service even with correct IAM roles. I have debugged this exact issue on client projects where instances appeared unmanaged despite perfect IAM configuration—the missing VPC endpoint was always the culprit.

Operator Permissions

Human users and automation scripts need separate permissions. The AmazonSSMFullAccess managed policy works for initial setup but is too broad for production. Create a custom policy scoped to specific resource tags or instance IDs:

  • ssm:SendCommand restricted to approved SSM documents only
  • ssm:StartSession limited to tagged production instances
  • ssm:GetCommandInvocation for viewing execution results
  • Explicit deny on ssm:UpdateDocument unless part of platform engineering team

This tag-based scoping prevents junior developers from accidentally running destructive commands against production databases while still allowing them to debug staging environments freely.

How do you execute remote commands at scale with Run Command?

Run Command is the workhorse of AWS Systems Manager: Automate Fleet Operations. It executes shell scripts, PowerShell commands, or Ansible playbooks across hundreds of instances simultaneously without writing custom orchestration code. Unlike ad-hoc SSH loops, every execution is logged to CloudTrail and output captured in S3 or CloudWatch Logs automatically.

OperatorCLI / ConsoleCI/CD PipelineGitLab / GitHubSSM ServiceRun Command APITarget ResolutionRate ControlProd Web TierTag: env=prodStaging WorkersTag: tier=workerHybrid On-PremActivation CodeAudit TrailCloudTrail + S3
Run Command execution flow: targets resolved by tags, rate-controlled, and fully audited

Targeting Instances Intelligently

Never target instances by ID in production automation. Use resource tags instead. Tags survive instance replacements during auto-scaling events and make your commands portable across environments. Combine multiple tag filters for precision:

aws ssm send-command \
  --document-name "AWS-RunShellScript" \
  --targets "Key=tag:Environment,Values=production" "Key=tag:Role,Values=webserver" \
  --parameters 'commands=["sudo systemctl restart php8.4-fpm","sudo systemctl status php8.4-fpm"]' \
  --max-concurrency "20%" \
  --max-errors "5%" \
  --output-s3-bucket-name "my-ssm-logs" \
  --region ap-south-1

The --max-concurrency and --max-errors parameters are critical safety valves. Setting concurrency to 20% ensures you never restart all web servers simultaneously during peak traffic. The error threshold stops execution if more than 5% of targets fail, preventing cascading failures from bad scripts. I treat these as mandatory, not optional—every production Run Command includes both.

Custom SSM Documents for Repeatable Tasks

While AWS-RunShellScript works for one-off debugging, create custom SSM documents for recurring operational tasks. Documents version-control your automation, accept typed parameters, and enforce validation before execution:

{
  "schemaVersion": "2.2",
  "description": "Clear Laravel caches and rebuild config",
  "parameters": {
    "AppPath": {
      "type": "String",
      "default": "/var/www/html/current",
      "description": "Laravel release path"
    }
  },
  "mainSteps": [
    {
      "action": "aws:runShellScript",
      "name": "ClearCaches",
      "inputs": {
        "runCommand": [
          "cd {{ AppPath }}",
          "sudo -u www-data php artisan config:clear",
          "sudo -u www-data php artisan cache:clear",
          "sudo -u www-data php artisan view:clear",
          "sudo -u www-data php artisan config:cache"
        ]
      }
    }
  ]
}

Store these documents in Git alongside your application code. Deploy them via CI/CD so your automation evolves with your application. This pattern keeps operational knowledge codified rather than trapped in individual engineers' heads or bash history files.

How does Patch Manager maintain compliance across mixed fleets?

Patch Manager transforms OS patching from a monthly fire drill into a predictable, automated workflow. It supports Amazon Linux, Ubuntu, Debian, RHEL, CentOS, and Windows Server from a single interface. More importantly, it separates patch approval from patch deployment—a distinction many teams miss until they accidentally push a breaking kernel update to production.

CapabilityManual PatchingSSM Patch Manager
Coverage VisibilitySpreadsheet tracking, stale dataReal-time compliance dashboard per instance
Approval WorkflowAd-hoc testing, tribal knowledgePatch baselines with explicit allow/deny lists
Maintenance WindowsCoordinated manually via chat/emailScheduled cron-like windows with timezone support
Rollback CapabilitySnapshot-dependent, slowPre-patch snapshots + documented rollback runbooks
Audit EvidenceScreenshots, log fragmentsAutomated compliance reports exportable to PDF/CSV
Hybrid SupportSeparate tooling per platformUnified baseline across cloud and on-premises

Create separate patch baselines for staging and production. Staging should auto-approve patches after 3 days of release; production might require 14 days plus manual approval for critical CVEs. Maintenance windows enforce when patches install regardless of approval state—this prevents 3 AM surprise reboots. For Nepal-based clients operating on NPT (UTC+5:45), always specify timezone explicitly in maintenance window schedules to avoid off-by-one-hour errors during BST transitions.

Patch Manager integrates natively with AWS Security Hub and Inspector. Compliance drift triggers automated alerts before auditors notice gaps. For legal-tech platforms handling sensitive case data, this continuous compliance evidence generation saves dozens of hours during annual security reviews.

When should you use Session Manager instead of SSH?

Session Manager provides interactive shell access without SSH keys, bastion hosts, or open ports. It is not a replacement for all SSH use cases—it is superior for debugging, inferior for file transfers and tunneling. Understanding when to use each prevents friction.

Need Server Access?Interactive Debugging?YESNOSession Manager✓ Full audit logging✓ No SSH keys neededConsider AlternativesFile transfer → S3 + cpPort forward → SSM tunnelBest For:Log inspection, config checksFallback To:SSH only if SSM unsupported
Decision framework: Session Manager for interactive debugging, alternatives for file transfers and tunnels

Enable Session Manager logging to S3 or CloudWatch Logs immediately. Every keystroke and command output gets recorded. This audit trail proved invaluable during a security review for a financial services client who needed to demonstrate exactly who accessed production servers and what they did. Traditional SSH leaves no such centralized record without additional tooling like Teleport or BastionZero.

For local development workflows requiring port forwarding (database GUIs, admin panels), SSM supports SSH-style tunneling without exposing ports publicly:

aws ssm start-session \
  --target i-0abc123def456 \
  --document-name AWS-StartPortForwardingSessionToRemoteHost \
  --parameters '{"host":["localhost"],"portNumber":["3306"], "localPortNumber":["3306"]}'

This forwards your local port 3306 directly to the RDS instance accessible only from the EC2 host. No VPN, no jump box, no security group changes. Developers get database access for debugging while the infrastructure team maintains zero public exposure. If you are exploring cloud hosting versus shared hosting, this capability alone often justifies the migration cost for teams needing secure developer access.

How do you integrate SSM with existing CI/CD and monitoring stacks?

SSM does not operate in isolation. Its real power emerges when integrated with your deployment pipelines and observability stack. Treat SSM documents as infrastructure-as-code artifacts stored in version control, deployed through the same CI/CD system as your application.

In GitLab CI pipelines I maintain for multiple sister sites sharing infrastructure, post-deployment jobs invoke SSM Run Command to clear caches, reload PHP-FPM, and verify health checks. The pipeline waits for command completion and fails the job if any target returns non-zero exit codes. This catches deployment issues before marking the release successful. Combined with DevOps automation best practices, this creates end-to-end visibility from commit to production verification.

Connect SSM OpsCenter to CloudWatch Alarms for automated remediation. When disk usage exceeds 85%, trigger an SSM Automation document that cleans temp files, rotates logs, and notifies Slack. When certificate expiry approaches, auto-renew via Certbot and reload Nginx. These self-healing patterns reduce pager fatigue and let engineers focus on feature work instead of repetitive firefighting.

Export SSM inventory data to Athena for long-term trend analysis. Track package versions, agent status, and compliance scores over months. This historical data informs capacity planning and identifies configuration drift before it causes incidents. For agencies managing dozens of client environments, this centralized visibility replaces fragmented spreadsheet tracking and missed renewal dates.

Practical Next Steps for AWS Systems Manager Adoption

Start with Session Manager to eliminate SSH keys across your fleet this week. Then implement Run Command for your three most frequent manual tasks. Finally, establish Patch Manager baselines aligned with your compliance requirements. Each step delivers immediate value while building toward comprehensive AWS Systems Manager: Automate Fleet Operations coverage. If your team needs hands-on implementation support or infrastructure assessment, reach out to discuss your specific environment.

Frequently Asked Questions

AWS Systems Manager centralizes operational management for EC2 instances and on-premises servers. It automates patching, configuration, inventory tracking, and remote command execution without requiring SSH access or bastion hosts across your infrastructure fleet.

SSM Agent uses outbound HTTPS connections to AWS endpoints, eliminating inbound port 22 requirements. This removes bastion host dependencies, reduces attack surface, and enables secure shell access through IAM policies rather than static key pairs stored on developer machines.

Attach the managed policy AmazonSSMManagedInstanceCore to instance profiles for agent communication. Operators need ssm:SendCommand, ssm:GetCommandInvocation, and ec2:DescribeInstances permissions. Avoid granting full AdministratorAccess; scope policies to specific resource tags and document names for least privilege.

Core capabilities like Run Command, State Manager, and Inventory are free for EC2 and on-premises nodes. Session Manager costs nothing for standard usage. OpsCenter and Explorer charge per API call after free tier. Patch Manager remains free regardless of fleet size.

Yes, install SSM Agent on on-premises Linux or Windows servers and activate them as hybrid managed nodes using an activation code and ID. These nodes appear alongside EC2 instances in Fleet Manager, supporting identical Run Command documents, patch baselines, and inventory collection workflows.

Verify the instance has outbound internet access to ssm.region.amazonaws.com on port 443. Check CloudWatch Logs under /aws/ssm/ for agent errors. Confirm the IAM role includes AmazonSSMManagedInstanceCore. Restart the agent service and validate the managed node status in Systems Manager console.

Run Command executes ad-hoc tasks immediately across targeted nodes. State Manager enforces desired configuration continuously by associating documents with schedules or targets. Use Run Command for debugging and one-time fixes; use State Manager for persistent compliance enforcement and automated drift correction.

Session Manager eliminates open inbound ports and SSH key distribution entirely. All sessions route through AWS infrastructure with full audit logging to CloudWatch and S3. Access controls via IAM policies replace shared credentials. Sessions can be restricted by tag, user, or time window for compliance.

Yes, Patch Manager supports Amazon Linux, Ubuntu, Debian, RHEL, CentOS, and SUSE with predefined or custom baselines. Create patch groups using tags, define approval rules per OS, and schedule maintenance windows. Test patches on non-production nodes first before applying to production fleets.

Use aws ssm send-command in GitLab CI or GitHub Actions to deploy configurations post-build. Store secrets in Parameter Store and reference them securely during deployment. Trigger State Manager associations after successful deployments to enforce runtime configuration consistency across all environment nodes.

Missing SSM Agent installation on older AMIs causes silent failures. Overly broad IAM policies create security risks. Forgetting to configure VPC endpoints increases NAT gateway costs. Not testing patch baselines leads to outages. Assuming free tier covers all features results in unexpected OpsCenter charges.

Parameter Store offers free standard parameters for configuration values and non-sensitive data. Secrets Manager provides automatic rotation, KMS encryption by default, and cross-account sharing for database credentials and API keys. Use Parameter Store for app config; use Secrets Manager for sensitive rotating credentials.

Yes, Inventory collects software, file, and registry metadata automatically. Compliance feature compares collected state against CIS benchmarks or custom rules. Generate reports showing non-compliant nodes, missing patches, or unauthorized software. Schedule recurring assessments and export findings to Security Hub or S3.

Commands timeout based on configured executionTimeout value, defaulting to 3600 seconds. Failed invocations appear in Command History with error details. Configure CloudWatch Alarms on SSM heartbeat metrics to detect unresponsive agents. Implement retry logic in automation runbooks for transient network failures.

Keep Ansible for complex orchestration and multi-cloud environments. Adopt SSM for AWS-native patching, inventory, and secure shell access without managing control nodes. Many teams run both: SSM handles baseline operations and compliance while Ansible manages application deployment and cross-provider provisioning tasks.

Share this article

Quick Contact Options
Choose how you want to connect me: