<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alpesh</title>
    <description>The latest articles on DEV Community by Alpesh (@alpeshkumbhare).</description>
    <link>https://dev.to/alpeshkumbhare</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4052950%2F69b38341-0628-422f-aa3f-392277754086.png</url>
      <title>DEV Community: Alpesh</title>
      <link>https://dev.to/alpeshkumbhare</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alpeshkumbhare"/>
    <language>en</language>
    <item>
      <title>Automating Amazon EVS (Elastic VMware Service) Day-0 to Day-2 Operations with CloudFormation and Step Functions</title>
      <dc:creator>Alpesh</dc:creator>
      <pubDate>Wed, 29 Jul 2026 10:38:55 +0000</pubDate>
      <link>https://dev.to/alpeshkumbhare/automating-amazon-evs-elastic-vmware-service-day-0-to-day-2-operations-with-cloudformation-and-383a</link>
      <guid>https://dev.to/alpeshkumbhare/automating-amazon-evs-elastic-vmware-service-day-0-to-day-2-operations-with-cloudformation-and-383a</guid>
      <description>&lt;p&gt;Amazon Elastic VMware Service (EVS) reached general availability in August 2025, enabling customers to run VMware Cloud Foundation (VCF) directly within their Amazon VPC. While EVS simplifies the infrastructure layer, operationalizing it at scale — provisioning environments, configuring vCenter, setting up NSX segments, attaching storage, and integrating with ITSM — still requires significant automation.&lt;/p&gt;

&lt;p&gt;This post presents a pattern for automating EVS from Day-0 (environment creation) through Day-2 (monitoring, alerting, billing) using AWS CloudFormation and Step Functions. The approach is modular, allowing teams to adopt individual components independently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge with EVS at Scale
&lt;/h2&gt;

&lt;p&gt;Standing up a single EVS environment involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a dedicated VPC with correct subnet sizing (/20 minimum)&lt;/li&gt;
&lt;li&gt;Deploying the EVS environment with Route Server and BGP peering&lt;/li&gt;
&lt;li&gt;Configuring vCenter and SDDC Manager (SSL certificates, depot credentials, domain settings)&lt;/li&gt;
&lt;li&gt;Creating NSX-T segments for workload networking&lt;/li&gt;
&lt;li&gt;Optionally deploying FSx for NetApp ONTAP as shared storage&lt;/li&gt;
&lt;li&gt;Setting up CloudWatch alarms for bare-metal host health&lt;/li&gt;
&lt;li&gt;Integrating with ITSM (ServiceNow) for incident management&lt;/li&gt;
&lt;li&gt;Tracking host counts for billing and reporting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When managing EVS across multiple accounts and regions, this must be repeatable, auditable, and hands-off.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: Modular CloudFormation with Step Function Orchestration
&lt;/h2&gt;

&lt;p&gt;The solution uses a modular approach — each operational concern is a separate CloudFormation stack, orchestrated by a central Step Function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ┌─────────────────────────┐
                    │  Step Function Orchestrator  │
                    └──────────┬──────────────┘
                               │
        ┌──────────────────────┼──────────────────────┐
        │                      │                      │
        ▼                      ▼                      ▼
┌───────────────┐    ┌──────────────────┐    ┌──────────────────┐
│  Pre-Setup    │    │ Network Creation │    │  EVS Environment │
│  (DDB, IAM)  │    │ (VPC, Subnets)   │    │  (Route Server,  │
│               │    │                  │    │   BGP, Deploy)   │
└───────────────┘    └──────────────────┘    └──────────────────┘
        │                      │                      │
        ▼                      ▼                      ▼
┌───────────────┐    ┌──────────────────┐    ┌──────────────────┐
│  Configure    │    │  NSX Segment     │    │  FSx ONTAP       │
│  vCenter/SDDC │    │  Creation        │    │  (Optional NFS)  │
└───────────────┘    └──────────────────┘    └──────────────────┘
        │                      │                      │
        ▼                      ▼                      ▼
┌───────────────┐    ┌──────────────────┐    ┌──────────────────┐
│  CW Alarms    │    │  ITSM / Alarm    │    │  Billing &amp;amp;       │
│  (Host Health)│    │  Event Handler   │    │  Reporting       │
└───────────────┘    └──────────────────┘    └──────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Design Principles
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;One stack, one concern&lt;/strong&gt; — Network, compute, storage, monitoring, and ITSM are independent stacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step Function as orchestrator&lt;/strong&gt; — Handles sequencing, retries, and cross-account coordination&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB for state&lt;/strong&gt; — Tracks deployment status, lock management, and host inventory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSM Parameter Store as configuration registry&lt;/strong&gt; — All naming conventions and cross-stack references flow through SSM&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Day-0: Environment Provisioning
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Network Foundation
&lt;/h3&gt;

&lt;p&gt;EVS requires a /20 CIDR minimum for the management VPC. The network stack provisions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dedicated VPC with DNS support enabled&lt;/li&gt;
&lt;li&gt;Private subnets in the target AZ (EVS is single-AZ per environment)&lt;/li&gt;
&lt;li&gt;Route tables prepared for BGP route injection from Route Server
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Key design decision: /20 minimum for EVS VPC&lt;/span&gt;
&lt;span class="na"&gt;Parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;CidrBlock&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10.23.0.0/20&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CIDR&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;block&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;EVS&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;VPC&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(minimum&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/20)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Route Server and EVS Deployment
&lt;/h3&gt;

&lt;p&gt;The EVS environment stack handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Route Server creation&lt;/strong&gt; with a private ASN (64512-65534 range)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BGP peer configuration&lt;/strong&gt; for NSX Edge connectivity (EVS uses BGP for overlay-to-underlay routing)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EVS environment deployment&lt;/strong&gt; with &lt;code&gt;i4i.metal&lt;/code&gt; instances, VMware license keys, and VCF configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route persistence&lt;/strong&gt; — keeps routes active briefly after BGP session drops to avoid routing flaps
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Route Server enables dynamic routing between EVS NSX and AWS VPC&lt;/span&gt;
&lt;span class="na"&gt;Parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;RouteServerASN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Number&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;65001&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ASN for Route Server (private range)&lt;/span&gt;
  &lt;span class="na"&gt;PeerASN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Number&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;65000&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ASN for EVS NSX Edge nodes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step Function Orchestration
&lt;/h3&gt;

&lt;p&gt;The central Step Function coordinates the multi-step deployment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check DynamoDB&lt;/strong&gt; — Validates the target account doesn't already have an EVS deployment (prevents duplicates)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-setup&lt;/strong&gt; — Creates DynamoDB state tables, IAM roles, and SSM parameters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network deployment&lt;/strong&gt; — Provisions VPC, subnets, and route tables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EVS environment creation&lt;/strong&gt; — Deploys Route Server and EVS cluster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post-install tasks&lt;/strong&gt; — Configures vCenter, creates NSX segments, deploys optional storage&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Step Function uses a &lt;strong&gt;DynamoDB-based locking mechanism&lt;/strong&gt; to prevent concurrent deployments to the same account — critical in multi-tenant managed service environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Day-1: Configuration Automation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  vCenter and SDDC Manager Configuration
&lt;/h3&gt;

&lt;p&gt;After EVS deploys the VCF stack, vCenter and SDDC Manager need configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSL certificate rotation (replacing self-signed certs with organization certificates)&lt;/li&gt;
&lt;li&gt;VMware Depot credentials for patching and updates&lt;/li&gt;
&lt;li&gt;Domain and DNS configuration&lt;/li&gt;
&lt;li&gt;NFS datastore mounting (if FSx ONTAP is deployed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This automation uses an EC2 jumphost (Windows Server) with SSM Run Command to execute PowerShell/PowerCLI scripts against vCenter and SDDC Manager APIs — necessary because these APIs are only accessible from within the VPC.&lt;/p&gt;

&lt;h3&gt;
  
  
  NSX-T Segment Creation
&lt;/h3&gt;

&lt;p&gt;Workload VMs need network segments. The NSX automation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieves NSX Manager credentials from Secrets Manager (stored during EVS deployment)&lt;/li&gt;
&lt;li&gt;Connects to the NSX Manager REST API via the EC2 jumphost&lt;/li&gt;
&lt;li&gt;Creates DHCP server profiles for workload subnets&lt;/li&gt;
&lt;li&gt;Provisions overlay segments with gateway and DHCP configuration
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# NSX segment creation via REST API (executed on jumphost via SSM)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$nsxManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"evs01-nsx01.customer.domain"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$headers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Authorization&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Basic &lt;/span&gt;&lt;span class="nv"&gt;$encodedCreds&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Create DHCP profile, then segment with gateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  FSx for NetApp ONTAP (Optional NFS Datastore)
&lt;/h3&gt;

&lt;p&gt;For environments needing shared storage beyond vSAN:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FSx ONTAP file system deployed in the EVS VPC subnet&lt;/li&gt;
&lt;li&gt;Storage Virtual Machine (SVM) created with NFS protocol&lt;/li&gt;
&lt;li&gt;Volume provisioned with specified capacity&lt;/li&gt;
&lt;li&gt;Security groups configured for NFS traffic from ESXi hosts
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# FSx ONTAP supports multiple deployment types&lt;/span&gt;
&lt;span class="na"&gt;Parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;DeploymentType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;AllowedValues&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MULTI_AZ_2&lt;/span&gt;   &lt;span class="c1"&gt;# Recommended: standby in second AZ&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SINGLE_AZ_2&lt;/span&gt;  &lt;span class="c1"&gt;# High performance: 6+ GBps&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MULTI_AZ_1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SINGLE_AZ_1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Day-2: Monitoring, Alerting, and Billing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CloudWatch Alarms for EVS Hosts
&lt;/h3&gt;

&lt;p&gt;EVS runs on bare-metal &lt;code&gt;i4i.metal&lt;/code&gt; instances. The monitoring stack:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Maintains a DynamoDB table of active EVS host instance IDs&lt;/li&gt;
&lt;li&gt;Uses DynamoDB Streams to detect when hosts are added or removed&lt;/li&gt;
&lt;li&gt;Automatically creates CloudWatch alarms for each host (CPU, status checks, network)&lt;/li&gt;
&lt;li&gt;All alarms publish to a central SNS topic&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is event-driven — when a new host is added to the DynamoDB table, alarms are created automatically. When a host is removed, alarms are cleaned up.&lt;/p&gt;

&lt;h3&gt;
  
  
  ITSM Integration (ServiceNow)
&lt;/h3&gt;

&lt;p&gt;Alarm events are routed through SQS to a Lambda that formats and forwards to ServiceNow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EVS-specific event category (&lt;code&gt;Cloud.PaaS.PCS-AWS-EVS&lt;/code&gt;) for proper routing&lt;/li&gt;
&lt;li&gt;SQS queue receives SNS alarm notifications&lt;/li&gt;
&lt;li&gt;Lambda formats events with severity, CI mapping, and remediation context&lt;/li&gt;
&lt;li&gt;Events forwarded to ServiceNow for automatic incident creation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Billing and Reporting
&lt;/h3&gt;

&lt;p&gt;A scheduled Lambda collects EVS environment details across accounts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Queries EVS API for host counts and configuration per account&lt;/li&gt;
&lt;li&gt;Stores data in DynamoDB (partitioned by AccountID + NodeName)&lt;/li&gt;
&lt;li&gt;Exports to S3 for reporting dashboards&lt;/li&gt;
&lt;li&gt;Enables per-tenant billing based on actual host consumption&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;EVS needs /20 CIDR minimum&lt;/strong&gt; — plan IP address space carefully, especially in multi-environment setups&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route Server + BGP is mandatory&lt;/strong&gt; — EVS NSX overlay routing requires dynamic BGP peering with a Route Server in the VPC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a jumphost for VMware API automation&lt;/strong&gt; — vCenter, SDDC Manager, and NSX APIs are VPC-internal; SSM Run Command on an EC2 instance is the cleanest pattern&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB Streams for reactive monitoring&lt;/strong&gt; — automatically provision/deprovision alarms as hosts come and go&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step Functions with DDB locking&lt;/strong&gt; — prevents race conditions in multi-tenant environments where multiple deployments could target the same account&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Amazon EVS brings VMware workloads into your VPC, but operationalizing it requires the same automation discipline as any other AWS service. The modular pattern described here — independent CloudFormation stacks orchestrated by Step Functions, with DynamoDB for state and SSM for configuration — scales from single environments to multi-account managed service platforms.&lt;/p&gt;

&lt;p&gt;For teams adopting EVS, investing in Day-0 automation pays dividends immediately: consistent deployments, faster time-to-environment, and a foundation for Day-2 operations that doesn't depend on manual intervention.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Alpesh Kumbhare is a Cloud Architect at Atos, specializing in AWS infrastructure automation and VMware cloud solutions. Connect on &lt;a&gt;LinkedIn&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>vmw</category>
      <category>cloudformation</category>
      <category>devops</category>
    </item>
    <item>
      <title>Automating Dell PowerProtect Backup on AWS: A Terraform-Based Approach</title>
      <dc:creator>Alpesh</dc:creator>
      <pubDate>Wed, 29 Jul 2026 10:20:07 +0000</pubDate>
      <link>https://dev.to/alpeshkumbhare/automating-dell-powerprotect-backup-on-aws-a-terraform-based-approach-pac</link>
      <guid>https://dev.to/alpeshkumbhare/automating-dell-powerprotect-backup-on-aws-a-terraform-based-approach-pac</guid>
      <description>&lt;p&gt;Organizations running Dell PowerProtect backup on AWS face a recurring challenge: the multi-appliance ecosystem — PPDM (PowerProtect Data Manager), DDVE (Data Domain Virtual Edition), and DDMC (Data Domain Management Center) — requires careful, sequenced provisioning that is difficult to repeat consistently across regions and accounts.&lt;/p&gt;

&lt;p&gt;This post presents an approach to automating Dell PowerProtect deployment on AWS using Terraform for infrastructure provisioning and AWS Step Functions for post-deployment orchestration. The patterns described here are applicable to any enterprise running Dell backup appliances on AWS and looking to move from manual or semi-automated deployments to a fully codified, repeatable framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Automate Dell Backup on AWS?
&lt;/h2&gt;

&lt;p&gt;Dell PowerProtect components on AWS are typically deployed as EC2 instances from marketplace AMIs. While the deployment itself is straightforward, the challenge lies in what comes after:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DDMC&lt;/strong&gt; requires an interactive first-login wizard (EULA acceptance, password change, filesystem setup)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PPDM&lt;/strong&gt; needs REST API-driven configuration (licensing, NTP, credential setup, policy creation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DDVE&lt;/strong&gt; must be registered with both PPDM and DDMC via coordinated API calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS resolution&lt;/strong&gt; must include both forward and reverse records — PPDM validates bidirectional DNS before accepting integration partners&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Credentials&lt;/strong&gt; need secure storage and rotation from day one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When done manually, this process introduces configuration drift, creates undocumented tribal knowledge, and doesn't scale. Infrastructure as Code eliminates these risks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference Architecture
&lt;/h2&gt;

&lt;p&gt;A production-grade Dell PowerProtect automation framework on AWS operates across four layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────────┐
│                    Layer 1: Terraform - Infrastructure                │
│  VPC / Subnets / Security Groups / Route53 / IAM / KMS / Secrets    │
├─────────────────────────────────────────────────────────────────────┤
│                    Layer 2: Terraform - Appliance Deployment          │
│  PPDM EC2 Instance / DDVE EC2 Instance / DDMC EC2 Instance          │
│  EBS Volumes / Network Interfaces / Instance Profiles                │
├─────────────────────────────────────────────────────────────────────┤
│                    Layer 3: Step Functions - Configuration            │
│  Lambda: Configure DDMC (SSH)                                        │
│  Lambda: Configure PPDM (REST API)                                   │
│  Lambda: Integrate DDVE ↔ PPDM/DDMC (REST API)                      │
│  Lambda: Credential Rotation (Secrets Manager)                       │
├─────────────────────────────────────────────────────────────────────┤
│                    Layer 4: Operational Monitoring                    │
│  EventBridge → Monitor Lambda → DynamoDB → ITSM Integration         │
└─────────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer has a clear responsibility boundary, and changes in one layer don't cascade unpredictably into others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: Network and Security Foundation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  VPC and Subnet Design
&lt;/h3&gt;

&lt;p&gt;Dell backup appliances communicate on specific ports (2051, 2052, 3009 for Data Domain protocols, 443 for management APIs). Your network module should provision:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A dedicated VPC (or subnet range within an existing VPC) for backup appliances&lt;/li&gt;
&lt;li&gt;Private subnets across multiple Availability Zones for resilience&lt;/li&gt;
&lt;li&gt;Security groups with granular ingress/egress rules scoped to Dell protocol ports&lt;/li&gt;
&lt;li&gt;NAT Gateway access for marketplace license validation and updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DNS: The Hidden Requirement
&lt;/h3&gt;

&lt;p&gt;A common deployment failure with PPDM is integration rejection due to DNS resolution issues. PPDM performs bidirectional DNS validation — it resolves the DDVE hostname to an IP, then reverse-resolves that IP back to a hostname, and expects them to match.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You must automate both:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forward DNS (A records) in Route53 private hosted zones&lt;/li&gt;
&lt;li&gt;Reverse DNS (PTR records) in reverse lookup zones (e.g., &lt;code&gt;10.in-addr.arpa&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without PTR records, PPDM will fail with errors like "Network validation has failed" or "Unable to resolve FQDN/IP address." This is not well documented and catches many teams off guard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Terraform reverse DNS zone and PTR record&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_route53_zone"&lt;/span&gt; &lt;span class="s2"&gt;"reverse"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.168.192.in-addr.arpa"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_route53_record"&lt;/span&gt; &lt;span class="s2"&gt;"ppdm_ptr"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;zone_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_route53_zone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;zone_id&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"15.10.168.192.in-addr.arpa"&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"PTR"&lt;/span&gt;
  &lt;span class="nx"&gt;ttl&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
  &lt;span class="nx"&gt;records&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ppdm.backup.internal"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  IAM and Secrets Management
&lt;/h3&gt;

&lt;p&gt;Each appliance role should follow least privilege:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PPDM instance role: access to Secrets Manager (own credentials), S3 (backup targets), SSM (for agent deployment)&lt;/li&gt;
&lt;li&gt;DDVE instance role: KMS decrypt for encrypted volumes, Secrets Manager for rotation&lt;/li&gt;
&lt;li&gt;DDMC instance role: SSM for parameter retrieval, EC2 DescribeInstances for discovery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Store initial and rotated credentials in AWS Secrets Manager from the start. Avoid embedding credentials in EC2 user data or relying on instance IDs as default passwords.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: Appliance Deployment with Terraform
&lt;/h2&gt;

&lt;p&gt;Each Dell appliance is an EC2 instance provisioned from marketplace AMIs. Key considerations:&lt;/p&gt;

&lt;h3&gt;
  
  
  PPDM Deployment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Instance type: &lt;code&gt;m5.xlarge&lt;/code&gt; or larger (4 vCPU, 16 GB RAM minimum)&lt;/li&gt;
&lt;li&gt;Root volume: 100 GB gp3&lt;/li&gt;
&lt;li&gt;Additional data volumes based on catalog size&lt;/li&gt;
&lt;li&gt;Elastic IP or stable private IP for DNS consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DDVE Deployment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Instance type: Storage-optimized (&lt;code&gt;m5.2xlarge&lt;/code&gt; or &lt;code&gt;r5.xlarge&lt;/code&gt; depending on capacity tier)&lt;/li&gt;
&lt;li&gt;Multiple EBS volumes for metadata and data (DDVE uses specific volume layouts)&lt;/li&gt;
&lt;li&gt;High IOPS configuration for deduplication workloads&lt;/li&gt;
&lt;li&gt;Consider io2 Block Express for large-scale deployments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DDMC Deployment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Instance type: &lt;code&gt;m5.large&lt;/code&gt; (lighter requirements as it's a management plane)&lt;/li&gt;
&lt;li&gt;Data volumes for its internal database&lt;/li&gt;
&lt;li&gt;Network access to all DDVE instances it will manage
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Parameterized appliance deployment&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"ppdm"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./modules/dell-appliance"&lt;/span&gt;
  &lt;span class="nx"&gt;appliance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ppdm"&lt;/span&gt;
  &lt;span class="nx"&gt;ami_id&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ppdm_ami_id&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ppdm_instance_type&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_id&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;private_subnet_ids&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;security_groups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ppdm_sg_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;iam_profile&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ppdm_instance_profile&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dell-backup"&lt;/span&gt;
    &lt;span class="nx"&gt;Component&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ppdm"&lt;/span&gt;
    &lt;span class="nx"&gt;Environment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key principle: Terraform handles the "what" (infrastructure state) but not the "how" (appliance-internal configuration). That's where Step Functions come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: Post-Deployment Configuration with Step Functions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Not Terraform Provisioners?
&lt;/h3&gt;

&lt;p&gt;Terraform provisioners (&lt;code&gt;remote-exec&lt;/code&gt;, &lt;code&gt;local-exec&lt;/code&gt;) are tempting but problematic for multi-step appliance configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They run at &lt;code&gt;terraform apply&lt;/code&gt; time and can't be retried independently&lt;/li&gt;
&lt;li&gt;They have no built-in state machine for sequential steps with wait conditions&lt;/li&gt;
&lt;li&gt;Failures leave Terraform state in an inconsistent position&lt;/li&gt;
&lt;li&gt;They break the declarative model — infrastructure becomes coupled with runtime behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS Step Functions provide a better fit: visible state machines with retry, timeout, branching, and independent execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration Lambda Functions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DDMC Configuration (SSH-based)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DDMC's first-login process is an interactive SSH shell wizard. A Lambda function using Paramiko (Python SSH library) automates this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect to DDMC via SSH (initial default credentials from Secrets Manager)&lt;/li&gt;
&lt;li&gt;Accept EULA prompts by pattern-matching terminal output&lt;/li&gt;
&lt;li&gt;Change the sysadmin password to a generated value&lt;/li&gt;
&lt;li&gt;Complete the setup wizard (timezone, hostname, network confirmation)&lt;/li&gt;
&lt;li&gt;Create the backup filesystem with defined quotas&lt;/li&gt;
&lt;li&gt;Store new credentials in Secrets Manager&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key challenge:&lt;/strong&gt; The wizard prompt text varies by DDMC firmware version. Build defensive pattern matching with timeouts and fallback detection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;PPDM Configuration (REST API-based)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PPDM exposes a REST API on port 443 after boot, but it takes 3-8 minutes after EC2 "running" state before the API becomes responsive. Your Lambda needs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Poll the PPDM API health endpoint with exponential backoff&lt;/li&gt;
&lt;li&gt;Authenticate with default credentials&lt;/li&gt;
&lt;li&gt;Accept the EULA via API&lt;/li&gt;
&lt;li&gt;Change the admin password&lt;/li&gt;
&lt;li&gt;Configure NTP settings&lt;/li&gt;
&lt;li&gt;Activate the license&lt;/li&gt;
&lt;li&gt;Create default protection policies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;DDVE-PPDM-DDMC Integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The integration Lambda orchestrates cross-appliance registration:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authenticate to PPDM API&lt;/li&gt;
&lt;li&gt;Add DDVE as a storage target in PPDM (requires DDVE credentials)&lt;/li&gt;
&lt;li&gt;Authenticate to DDMC API&lt;/li&gt;
&lt;li&gt;Register DDVE instance in DDMC&lt;/li&gt;
&lt;li&gt;Validate integration via status checks&lt;/li&gt;
&lt;li&gt;Run a test backup to confirm end-to-end connectivity&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step Function Definition
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"StartAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WaitForAppliances"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"States"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"WaitForAppliances"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Wait"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ConfigureDDMC"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ConfigureDDMC"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:lambda:...:configure-ddmc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Retry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"ErrorEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"States.ALL"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"IntervalSeconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"MaxAttempts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"BackoffRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ConfigurePPDM"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ConfigurePPDM"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:lambda:...:configure-ppdm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Retry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"ErrorEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"States.ALL"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"IntervalSeconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"MaxAttempts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"BackoffRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IntegrateDDVE"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"IntegrateDDVE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:lambda:...:integrate-ddve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Retry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"ErrorEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"States.ALL"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"IntervalSeconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"MaxAttempts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"BackoffRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"End"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Layer 4: Operational Monitoring and ITSM Integration
&lt;/h2&gt;

&lt;p&gt;Once deployed, Dell backup appliances need proactive monitoring. A serverless monitoring pattern works well:&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring Architecture
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;EventBridge Scheduled Rule&lt;/strong&gt; — Triggers a monitor Lambda every 10 minutes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor Lambda&lt;/strong&gt; — Authenticates to DDMC REST API, retrieves DDVE health status and active alerts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB Table&lt;/strong&gt; — Stores current alert state for deduplication and tracking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB Streams&lt;/strong&gt; — Triggers ITSM Lambda on new or changed alerts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ITSM Lambda&lt;/strong&gt; — Formats events and forwards to your incident management system (ServiceNow, Jira Service Management, etc.)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Alert Event Schema
&lt;/h3&gt;

&lt;p&gt;Standardize your event format for downstream consumption:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unique-uuid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dell-backup-monitor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"critical"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"appliance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ddve-01.backup.internal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alert_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Appliance Not Responding"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-15T10:30:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eu-west-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action_required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Investigate DDVE connectivity"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Event Archival
&lt;/h3&gt;

&lt;p&gt;Archive all events to S3 with structured paths for audit and compliance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;s3://backup-events/{service}/{account_id}/{region}/{date}/{event_id}-{severity}.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  EC2 Backup Onboarding at Scale
&lt;/h2&gt;

&lt;p&gt;The final automation piece is onboarding EC2 instances to Dell Backup protection:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tag-based targeting&lt;/strong&gt; — Instances tagged with &lt;code&gt;Backup: enabled&lt;/code&gt; are discovered&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSM Automation&lt;/strong&gt; — AWS Systems Manager installs the PPDM agent without SSH access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent registration&lt;/strong&gt; — The agent registers with PPDM using pre-configured server endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy assignment&lt;/strong&gt; — Protection policies are assigned based on workload tags (e.g., &lt;code&gt;BackupPolicy: daily-30day-retention&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health validation&lt;/strong&gt; — Post-installation check confirms agent connectivity to PPDM&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keep backup onboarding as a standalone automation — don't couple it with general EC2 lifecycle management. Backup policies change independently of OS patching or scaling events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Pitfalls and How to Avoid Them
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pitfall&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Missing PTR records&lt;/td&gt;
&lt;td&gt;PPDM integration fails silently&lt;/td&gt;
&lt;td&gt;Automate reverse DNS in your network module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default passwords left in place&lt;/td&gt;
&lt;td&gt;Security vulnerability&lt;/td&gt;
&lt;td&gt;Rotate on first boot, store in Secrets Manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Using Terraform provisioners for config&lt;/td&gt;
&lt;td&gt;Brittle, non-retryable deployments&lt;/td&gt;
&lt;td&gt;Use Step Functions + Lambda instead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No health checks between steps&lt;/td&gt;
&lt;td&gt;Integration attempts on unready appliances&lt;/td&gt;
&lt;td&gt;Implement polling with backoff in each Lambda&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coupling backup to OS management&lt;/td&gt;
&lt;td&gt;Change in one breaks the other&lt;/td&gt;
&lt;td&gt;Separate Terraform modules and pipelines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No monitoring of the monitoring&lt;/td&gt;
&lt;td&gt;Silent alerting failures&lt;/td&gt;
&lt;td&gt;CloudWatch Alarms on Lambda error metrics&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Automating Dell PowerProtect on AWS requires thinking in layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Terraform for infrastructure&lt;/strong&gt; — VPC, EC2, IAM, DNS (including reverse), KMS, Secrets Manager&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step Functions for orchestration&lt;/strong&gt; — Sequential, retryable configuration of appliances via Lambda&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EventBridge + Lambda for monitoring&lt;/strong&gt; — Proactive health checks with ITSM integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSM for onboarding&lt;/strong&gt; — Agent deployment at scale without SSH access&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The pattern separates concerns cleanly: Terraform owns state, Step Functions own workflow, Lambda owns appliance-specific logic. This separation makes each layer independently testable, updatable, and debuggable.&lt;/p&gt;

&lt;p&gt;For teams deploying Dell backup on AWS manually today, adopting this layered automation approach eliminates configuration drift, improves security posture, and scales across regions without additional engineering effort per deployment.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Alpesh Kumbhare is a Cloud Architect at Atos business, specializing in AWS infrastructure automation and enterprise data protection solutions. Connect on &lt;a href="https://www.linkedin.com/in/alpesh-kumbhare-a638b51b/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
