<?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: Mawuli Denteh</title>
    <description>The latest articles on DEV Community by Mawuli Denteh (@mawulikode).</description>
    <link>https://dev.to/mawulikode</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1117990%2F5edc9eed-f107-43b1-a8ef-431a3344cb33.jpeg</url>
      <title>DEV Community: Mawuli Denteh</title>
      <link>https://dev.to/mawulikode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mawulikode"/>
    <language>en</language>
    <item>
      <title>Cross-region data transfer from NFS server to Amazon EFS file system using AWS DataSync</title>
      <dc:creator>Mawuli Denteh</dc:creator>
      <pubDate>Tue, 28 Apr 2026 00:08:33 +0000</pubDate>
      <link>https://dev.to/aws-builders/cross-region-data-transfer-from-nfs-server-to-amazon-efs-file-system-using-aws-datasync-23i0</link>
      <guid>https://dev.to/aws-builders/cross-region-data-transfer-from-nfs-server-to-amazon-efs-file-system-using-aws-datasync-23i0</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This &lt;strong&gt;AWS DataSync&lt;/strong&gt; solution transfers data from an EC2-hosted NFS share in VPC A (us-east-1) to an Amazon EFS file system in VPC B (us-west-2). The two VPCs are connected through a peering connection. This setup simulates a typical on-premises to cloud data migration scenario.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;NFS server&lt;/strong&gt; uses the NFS protocol to share files and directories over a network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon EFS&lt;/strong&gt; is a fully managed, serverless cloud file storage service that provides elastic, shared file storage for Linux-based workloads and applications running on AWS services like EC2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS DataSync&lt;/strong&gt;, a fully managed, high-speed data transfer service, communicates with both storage locations via VPC endpoints, utilizing a private, fast and secure connection to accomplish the transfer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VPC Endpoints&lt;/strong&gt; provide private interface entry points to AWS services from within a VPC. While many AWS services have public endpoints that can be accessed over the internet, it is a best practice to use VPC endpoints to communicate with AWS services securely from within a VPC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Diagram
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd27cfdmch0nybz.cloudfront.net%2Fblog-demos%2Fdatasync-nfs-to-efs%2FDataSyncBlog-PRIVATE-white.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd27cfdmch0nybz.cloudfront.net%2Fblog-demos%2Fdatasync-nfs-to-efs%2FDataSyncBlog-PRIVATE-white.png" alt="extra-large Architecture diagram" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  US-EAST-1
&lt;/h2&gt;

&lt;h2&gt;
  
  
  VPC A
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a VPC A in &lt;strong&gt;us-east-1&lt;/strong&gt; with &lt;strong&gt;10.0.0.0/16&lt;/strong&gt; Cidr.&lt;/li&gt;
&lt;li&gt;Create &lt;strong&gt;two&lt;/strong&gt; public subnets and an internet gateway.&lt;/li&gt;
&lt;li&gt;Create &lt;strong&gt;two&lt;/strong&gt; private subnets and a nat gateway.&lt;/li&gt;
&lt;li&gt;Create an &lt;strong&gt;SSM Endpoint security group&lt;/strong&gt; with the following rules:

&lt;ol&gt;
&lt;li&gt;Inbound: 

&lt;ol&gt;
&lt;li&gt;HTTPS from VPC A.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Outbound

&lt;ol&gt;
&lt;li&gt;All traffic to VPC A.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;li&gt;Set up &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/fleet-manager-default-host-management-configuration.html" rel="noopener noreferrer"&gt;SSM Default Host Management Configuration&lt;/a&gt; to enable &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html" rel="noopener noreferrer"&gt;Session Manager&lt;/a&gt; to access the NFS server. You can optionally use a bastion host to access the NFS server.&lt;/li&gt;

&lt;li&gt;Use the default Host Management role or &lt;a href="https://us-east-1.console.aws.amazon.com/iam/home?region=us-east-1#/roles/create" rel="noopener noreferrer"&gt;create&lt;/a&gt; and attach an EC2 role to the NFS server for session manager to work. Attach the following AWS managed policies to the EC2 role:

&lt;ol&gt;
&lt;li&gt;AmazonSSMManagedEC2InstanceDefaultPolicy&lt;/li&gt;
&lt;li&gt;AmazonSSMManagedInstanceCore&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5lx7xmuoyvjnwpckxtp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5lx7xmuoyvjnwpckxtp.png" alt="extra-large Architecture diagram" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  VPC A Endpoints
&lt;/h2&gt;

&lt;p&gt;Create a VPC endpoint each for &lt;strong&gt;SSM&lt;/strong&gt;, &lt;strong&gt;EC2-Messages, and SSM-Messages&lt;/strong&gt; as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://us-east-1.console.aws.amazon.com/vpcconsole/home?region=us-east-1#CreateVpcEndpoint:" rel="noopener noreferrer"&gt;Create endpoint&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Optional name.&lt;/li&gt;
&lt;li&gt;Choose “&lt;strong&gt;AWS services&lt;/strong&gt;” type.&lt;/li&gt;
&lt;li&gt;Type “ssm” and search.&lt;/li&gt;
&lt;li&gt;Select the first option &lt;strong&gt;com.amazonaws.us-east-1.ssm.&lt;/strong&gt; The name varies according to the service.&lt;/li&gt;
&lt;li&gt;Next, select VPC A.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check&lt;/strong&gt; “Enable private DNS name”.&lt;/li&gt;
&lt;li&gt;DNS record IP type: &lt;strong&gt;IPv4&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnets.&lt;/strong&gt; Check the first two Availability Zones in the list. Under &lt;strong&gt;Subnet ID&lt;/strong&gt;, select both private subnets.&lt;/li&gt;
&lt;li&gt;IP address type: &lt;strong&gt;IPv4.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Security groups: Use the &lt;strong&gt;SSM Endpoint Security Group&lt;/strong&gt; created earlier. You will use this security group for all VPC endpoints in region A.&lt;/li&gt;
&lt;li&gt;Policy: &lt;strong&gt;Full access.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foe6z63lc4l13celyuaxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foe6z63lc4l13celyuaxz.png" alt="extra-large Architecture diagram" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  NFS Server
&lt;/h2&gt;

&lt;p&gt;Create the NFS server with the following specifications:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#LaunchInstances:" rel="noopener noreferrer"&gt;Launch instances&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Linux&lt;/strong&gt; AMI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;t2.micro&lt;/strong&gt; instance type.&lt;/li&gt;
&lt;li&gt;Proceed &lt;strong&gt;without&lt;/strong&gt; a key pair.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PrivateSubnetA.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Auto-assign public IP &lt;strong&gt;disabled.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create&lt;/strong&gt; NFS server security group:

&lt;ol&gt;
&lt;li&gt;Inbound: 

&lt;ol&gt;
&lt;li&gt;HTTPS from SSM Endpoint.&lt;/li&gt;
&lt;li&gt;NFS from VPC B.&lt;/li&gt;
&lt;li&gt;ICMP from VPC B.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Outbound

&lt;ol&gt;
&lt;li&gt;All traffic to VPC A and B.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;8 GB gp3&lt;/strong&gt; EBS volume.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;User data&lt;/strong&gt; for NFS server. Creates and exports NFS share, generates files for the transfer.
&lt;/li&gt;

&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;180
&lt;span class="c"&gt;# Check if the secondary drive exists&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; lsblk /dev/xvdb &amp;amp;&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; “/dev/xvdb not found. Exiting.”
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

&lt;/span&gt;mkfs.ext4 /dev/xvdb
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/data
mount /dev/xvdb /mnt/data
&lt;span class="nb"&gt;echo&lt;/span&gt; ‘/dev/xvdb /mnt/data ext4 defaults,nofail 0 2’ | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/fstab

&lt;span class="c"&gt;# Create and set up NFS share directory&lt;/span&gt;
&lt;span class="nv"&gt;TARGET_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;”/mnt/data/nfs_share”
&lt;span class="nv"&gt;PREFIX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;”test”
&lt;span class="nv"&gt;EXT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;”.txt”
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nv"&gt;$TARGET_DIR&lt;/span&gt;
&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; nobody:nobody &lt;span class="nv"&gt;$TARGET_DIR&lt;/span&gt;
&lt;span class="nb"&gt;chmod &lt;/span&gt;777 &lt;span class="nv"&gt;$TARGET_DIR&lt;/span&gt;

&lt;span class="c"&gt;# Function to generate files&lt;/span&gt;
generate_files&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;
&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;size_range&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$3&lt;/span&gt;
&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;block_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$4&lt;/span&gt;
&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;group_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$5&lt;/span&gt;

&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;start_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; “Starting generation of &lt;span class="nv"&gt;$group_label&lt;/span&gt; at &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;”

&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; “%04g” &lt;span class="nv"&gt;$start&lt;/span&gt; &lt;span class="nv"&gt;$end&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;”&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TARGET_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PREFIX&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;EXT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;”
    &lt;span class="nv"&gt;SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;RANDOM &lt;span class="o"&gt;%&lt;/span&gt; size_range &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="nb"&gt;dd &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/urandom &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;”&lt;span class="nv"&gt;$FILE&lt;/span&gt;” &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$block_size&lt;/span&gt; &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$SIZE&lt;/span&gt; &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;none &amp;amp;
&lt;span class="k"&gt;done
&lt;/span&gt;&lt;span class="nb"&gt;wait

local &lt;/span&gt;&lt;span class="nv"&gt;end_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; “Finished generation of &lt;span class="nv"&gt;$group_label&lt;/span&gt; at &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;”
&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;elapsed_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;end_time &lt;span class="o"&gt;-&lt;/span&gt; start_time&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; “Time taken &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;$group_label&lt;/span&gt;: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;elapsed_time&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; seconds”
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Generate file groups with time tracking&lt;/span&gt;
generate_files 1 1000 100 1K “1000 files &lt;span class="o"&gt;(&lt;/span&gt;1KB to 100KB&lt;span class="o"&gt;)&lt;/span&gt;” &amp;amp;
generate_files 1001 1100 100 1M “100 files &lt;span class="o"&gt;(&lt;/span&gt;1MB to 100MB&lt;span class="o"&gt;)&lt;/span&gt;” &amp;amp;

&lt;span class="nb"&gt;wait
echo&lt;/span&gt; “File generation &lt;span class="nb"&gt;complete &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$TARGET_DIR&lt;/span&gt;”

&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; “&lt;span class="se"&gt;\|&lt;/span&gt;^&lt;span class="nv"&gt;$TARGET_DIR&lt;/span&gt; |d” /etc/exports
&lt;span class="nb"&gt;echo&lt;/span&gt; “&lt;span class="nv"&gt;$TARGET_DIR&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;rw,sync,no_root_squash,no_all_squash&lt;span class="o"&gt;)&lt;/span&gt;” | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/exports &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
systemctl start nfs-server
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;nfs-server
exportfs &lt;span class="nt"&gt;-rav&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify that you can connect to the NFS server via Session Manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  US-WEST-2
&lt;/h2&gt;

&lt;h2&gt;
  
  
  VPC B
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a target VPC in &lt;strong&gt;us-west-2&lt;/strong&gt; with &lt;strong&gt;172.31.0.0/16&lt;/strong&gt; Cidr.&lt;/li&gt;
&lt;li&gt;Create &lt;strong&gt;two&lt;/strong&gt; public subnets and an internet gateway.&lt;/li&gt;
&lt;li&gt;Create &lt;strong&gt;two&lt;/strong&gt; private subnets and a NAT gateway.&lt;/li&gt;
&lt;li&gt;Follow the same steps as in Region A to enable Session Manager to access the NFS client.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create and attach an &lt;strong&gt;SSM Endpoint Security Group&lt;/strong&gt; to all the endpoints:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inbound: 

&lt;ol&gt;
&lt;li&gt;HTTPS from DataSync agent.&lt;/li&gt;
&lt;li&gt;NFS from VPC B.&lt;/li&gt;
&lt;li&gt;1024 – 1064 from DataSync agent.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Outbound

&lt;ol&gt;
&lt;li&gt;All traffic to VPC B.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Attach the same EC2 role created from VPC A to the NFS client if you are in the same account. For different accounts, you need to create a new EC2 role for the NFS client.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;a href="https://us-west-2.console.aws.amazon.com/iam/home?region=us-west-2#/roles/create" rel="noopener noreferrer"&gt;Create&lt;/a&gt; and attach an EC2 role to the DataSync agent. Attach the following AWS managed policies to the role:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWSDataSyncFullAccess&lt;/li&gt;
&lt;li&gt;AmazonSSMManagedEC2InstanceDefaultPolicy&lt;/li&gt;
&lt;li&gt;AmazonSSMManagedInstanceCore&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  DataSync Agent
&lt;/h2&gt;

&lt;p&gt;Create the DataSync agent using the specifications below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/datasync/latest/userguide/deploy-agents.html#ec2-deploy-agent" rel="noopener noreferrer"&gt;DataSync latest AMI&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;t3.micro&lt;/strong&gt; instance type.&lt;/li&gt;
&lt;li&gt;Proceed &lt;strong&gt;without&lt;/strong&gt; a key pair.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PrivateSubnetA.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Auto-assign public IP &lt;strong&gt;disabled.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;DataSync agent security group&lt;/strong&gt; as follows:

&lt;ol&gt;
&lt;li&gt;Inbound: 

&lt;ol&gt;
&lt;li&gt;HTTPS from VPC B.&lt;/li&gt;
&lt;li&gt;HTTP from NFS client.&lt;/li&gt;
&lt;li&gt;ICMP from NFS client.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Outbound

&lt;ol&gt;
&lt;li&gt;All traffic to VPC A and B.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;20 GB gp3&lt;/strong&gt; EBS volume.&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  VPC B Endpoints
&lt;/h2&gt;

&lt;p&gt;Follow similar procedures from &lt;strong&gt;US-EAST-1&lt;/strong&gt; to create VPC endpoints for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SSM.&lt;/li&gt;
&lt;li&gt;EC2-Messages.&lt;/li&gt;
&lt;li&gt;SSM-Messages.&lt;/li&gt;
&lt;li&gt;EFS.&lt;/li&gt;
&lt;li&gt;DataSync.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fim12vtd5m1qgmdb80eif.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fim12vtd5m1qgmdb80eif.png" alt="extra-large Architecture diagram" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  NFS Client
&lt;/h2&gt;

&lt;p&gt;Create the NFS client EC2 as shown below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://us-west-2.console.aws.amazon.com/ec2/home?region=us-west-2#LaunchInstances:" rel="noopener noreferrer"&gt;Launch instances&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Linux&lt;/strong&gt; AMI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;t2.micro&lt;/strong&gt; instance type.&lt;/li&gt;
&lt;li&gt;Proceed &lt;strong&gt;without&lt;/strong&gt; a key pair.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PrivateSubnetA&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Create an &lt;strong&gt;NFS client security group&lt;/strong&gt;:

&lt;ol&gt;
&lt;li&gt;Inbound: 

&lt;ol&gt;
&lt;li&gt;HTTPS from VPC B.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Outbound

&lt;ol&gt;
&lt;li&gt;All traffic to VPC A and B.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;8 GB gp3&lt;/strong&gt; EBS volume.&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  EFS file system
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create an &lt;strong&gt;EFS Security Group&lt;/strong&gt; with the following rules:

&lt;ol&gt;
&lt;li&gt;Inbound: 

&lt;ol&gt;
&lt;li&gt;NFS traffic from VPC B.&lt;/li&gt;
&lt;li&gt;NFS traffic from NFS Client.&lt;/li&gt;
&lt;li&gt;NFS traffic from DataSync agent. &lt;/li&gt;
&lt;li&gt;NFS traffic from SSM Endpoint.&lt;/li&gt;
&lt;li&gt;HTTPS from VPC B and SSM Endpoint.&lt;/li&gt;
&lt;li&gt;ICMP from NFS client.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Outbound

&lt;ol&gt;
&lt;li&gt;All traffic to VPC B.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://us-west-2.console.aws.amazon.com/efs/home?region=us-west-2#/get-started" rel="noopener noreferrer"&gt;Create file system&lt;/a&gt;.&lt;/li&gt;

&lt;li&gt;Select the target VPC.&lt;/li&gt;

&lt;li&gt;Keep the recommended settings and &lt;strong&gt;Create file system.&lt;/strong&gt;
&lt;/li&gt;

&lt;li&gt;Click on the file system ID.&lt;/li&gt;

&lt;li&gt;Go to the &lt;strong&gt;Network&lt;/strong&gt; tab.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Manage&lt;/strong&gt;.&lt;/li&gt;

&lt;li&gt;For the two mount points, edit the security groups to use only the earlier created &lt;strong&gt;EFS Security Group.&lt;/strong&gt;
&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  VPC Peering
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://us-east-1.console.aws.amazon.com/vpcconsole/home?region=us-east-1#CreatePeeringConnection:" rel="noopener noreferrer"&gt;Create peering connection&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Optional name.&lt;/li&gt;
&lt;li&gt;VPC ID (Requester): &lt;strong&gt;VPC A ID.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select another VPC to peer with: &lt;strong&gt;My account.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Region: &lt;strong&gt;Another Region.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;VPC ID (Accepter): &lt;strong&gt;VPC B ID.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwaj8f774kh818ksat4aq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwaj8f774kh818ksat4aq.png" alt="extra-large Architecture diagram" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;From Region B (us-west-2) &lt;a href="https://us-west-2.console.aws.amazon.com/vpcconsole/home?region=us-west-2#PeeringConnections:" rel="noopener noreferrer"&gt;Peering Connections&lt;/a&gt;, select the peering connection available. &lt;/li&gt;
&lt;li&gt;From the “Actions” menu, &lt;strong&gt;Accept request&lt;/strong&gt;. Confirm.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmn0nmzcnik3rjafhhb9h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmn0nmzcnik3rjafhhb9h.png" alt="extra-large Architecture diagram" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update the private route table for VPC A to forward Region B traffic to the peering connection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2wi28l83a1ojtukk7yp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2wi28l83a1ojtukk7yp.png" alt="extra-large Architecture diagram" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update the private route table for VPC B to forward Region A traffic to the peering connection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figcssaduw3pemei8kc81.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figcssaduw3pemei8kc81.png" alt="extra-large Architecture diagram" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Systems Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mount the NFS share
&lt;/h3&gt;

&lt;p&gt;Connect to the NFS client via Session Manager.&lt;br&gt;
Mount the NFS share from the NFS client over the peering connection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ping the NFS server to verify connection&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 5 10.0.x.x

&lt;span class="c"&gt;# Mount NFS server&lt;/span&gt;
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/nfs
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-t&lt;/span&gt; nfs 10.0.x.x:/mnt/data/nfs_share /mnt/nfs &lt;span class="nt"&gt;-o&lt;/span&gt; rw,sync

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm84bii3mok8piix3c8rd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm84bii3mok8piix3c8rd.png" alt="extra-large Architecture diagram" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrlew3axvzvp8iwiu999.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrlew3axvzvp8iwiu999.png" alt="extra-large Architecture diagram" width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Mount the EFS file system
&lt;/h3&gt;

&lt;p&gt;Mount the EFS file system from the NFS client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Mount EFS file system&lt;/span&gt;
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/efs

&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-t&lt;/span&gt; nfs4 &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;nfsvers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4.1,rsize&lt;span class="o"&gt;=&lt;/span&gt;1048576,wsize&lt;span class="o"&gt;=&lt;/span&gt;1048576,hard,timeo&lt;span class="o"&gt;=&lt;/span&gt;600,retrans&lt;span class="o"&gt;=&lt;/span&gt;2,noresvport fs-xxxxxxxxxxxxxxx.efs.us-west-2.amazonaws.com:/ /mnt/efs
OR
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-t&lt;/span&gt; nfs4 &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-t&lt;/span&gt; nfs4 &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;nfsvers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4.1,rsize&lt;span class="o"&gt;=&lt;/span&gt;1048576,wsize&lt;span class="o"&gt;=&lt;/span&gt;1048576,hard,timeo&lt;span class="o"&gt;=&lt;/span&gt;600,retrans&lt;span class="o"&gt;=&lt;/span&gt;2,noresvport 172.31.x.x:/ /mnt/efs

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23ar7hyxx9e3y09hvzyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23ar7hyxx9e3y09hvzyz.png" alt="extra-large Architecture diagram" width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  DataSync agent
&lt;/h3&gt;

&lt;p&gt;Obtain the activation code of the DataSync agent from the NFS client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test connectivity to the agent&lt;/span&gt;
nc &lt;span class="nt"&gt;-vz&lt;/span&gt; 172.31.x.x 80 

&lt;span class="c"&gt;# Obtain activation code&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;curl “http://&amp;lt;datasync-agent-ip&amp;gt;/?gatewayType&lt;span class="o"&gt;=&lt;/span&gt;SYNC&amp;amp;activationRegion&lt;span class="o"&gt;=&lt;/span&gt;us-west-2&amp;amp;privateLinkEndpoint&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;datasync-vpce-ip&amp;gt;&amp;amp;endpointType&lt;span class="o"&gt;=&lt;/span&gt;PRIVATE_LINK&amp;amp;no_redirect”

&lt;span class="c"&gt;# NB: Replace &amp;lt;datasync-agent-ip&amp;gt; and &amp;lt;datasync-vpce-ip&amp;gt; with actual values&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Activate the DataSync agent using the activation key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws datasync create-agent &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--agent-name&lt;/span&gt; “datasync-agent” &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--activation-key&lt;/span&gt; “xxxxx-xxxxx-xxxxx-xxxxx-xxxxx” &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--vpc-endpoint-id&lt;/span&gt; “vpce-xxxxxxxxxxxxxxxxx” &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--subnet-arns&lt;/span&gt; “arn:aws:ec2:us-west-2:accountId:subnet/subnet-xxxxxxxxxxx” &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--security-group-arns&lt;/span&gt; “arn:aws:ec2:us-west-2:accountId:security-group/sg-xxxxxxxxxxxx”

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the NFS location.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws datasync create-location-nfs &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--server-hostname&lt;/span&gt; “10.0.x.x” &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--subdirectory&lt;/span&gt; “/mnt/data/nfs_share” &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--on-prem-config&lt;/span&gt; &lt;span class="nv"&gt;AgentArns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;”arn:aws:datasync:us-west-2:accountId:agent/agent-xxxxxxxxxxx”

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the EFS location.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws datasync create-location-efs &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--efs-filesystem-arn&lt;/span&gt; “arn:aws:elasticfilesystem:us-west-2:accountId:file-system/fs-xxxxxxxxxxxxx” &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--ec2-config&lt;/span&gt; &lt;span class="nv"&gt;SubnetArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;”arn:aws:ec2:us-west-2:accountId:subnet/subnet-xxxxxxxxxxxxx”,SecurityGroupArns&lt;span class="o"&gt;=&lt;/span&gt;”arn:aws:ec2:us-west-2:accountId:security-group/sg-xxxxxxxxxxxxxxx”

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a task that connects both locations and start the task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws datasync create-task &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--source-location-arn&lt;/span&gt; “arn:aws:datasync:us-west-2:accountId:location/loc-xxxxxxxxxxxxxx” &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--destination-location-arn&lt;/span&gt; “arn:aws:datasync:us-west-2:accountId:location/loc-xxxxxxxxxxxxxx”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclbqs4cgntese4a3on62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclbqs4cgntese4a3on62.png" alt="extra-large Architecture diagram" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  YouTube Tutorial
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/fN2DKFsdVks"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/datasync/latest/userguide/what-is-datasync.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/datasync/latest/userguide/what-is-datasync.html&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/fleet-manager-default-host-management-configuration.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/systems-manager/latest/userguide/fleet-manager-default-host-management-configuration.html&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/datasync/latest/userguide/datasync-network.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/datasync/latest/userguide/datasync-network.html&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>data</category>
      <category>networking</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create a cloud-backed IDE for development</title>
      <dc:creator>Mawuli Denteh</dc:creator>
      <pubDate>Thu, 23 Oct 2025 23:32:19 +0000</pubDate>
      <link>https://dev.to/aws-builders/create-a-cloud-backed-ide-for-development-1f64</link>
      <guid>https://dev.to/aws-builders/create-a-cloud-backed-ide-for-development-1f64</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;I find it burdensome creating and configuring my development environment all over again when using a new laptop or system.&lt;/p&gt;

&lt;p&gt;The need for speed when installing packages, extensions, and compiling code is also very important, and the network plays a big role in that.&lt;/p&gt;

&lt;p&gt;After setting it all up, I also don’t want anything to disrupt the environment. I also want to be able to log in or access it reliably and easily anytime I need from any machine without having to set it all up again.&lt;/p&gt;

&lt;p&gt;Having dealt with this scenario many times, I found a way to create this environment, call upon it when I need and put it off when I don’t — and also have the ability to back it up anytime I make progress with new states of the storage/system.&lt;/p&gt;

&lt;p&gt;This may not be for everyone, but I think many developers may find value in this setup depending on their situation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Create a Linux server in the cloud and use &lt;strong&gt;VS Code’s Remote SSH&lt;/strong&gt; feature to securely access it, with the capability to manage the file system from the editor like you would locally.  &lt;/p&gt;

&lt;p&gt;I call it “The DevBox”. Sounds cool, doesn’t it? Let’s build it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cost Considerations
&lt;/h2&gt;

&lt;p&gt;This solution is going to cost a roughly fixed amount per month for &lt;strong&gt;EBS storage and snapshots (minimal)&lt;/strong&gt; and a variable amount for &lt;strong&gt;EC2 compute&lt;/strong&gt;, depending on how many hours you keep the server up in a month.  &lt;/p&gt;

&lt;p&gt;Take note and check the cost of what you are going to build (using the &lt;strong&gt;AWS Pricing Calculator&lt;/strong&gt;) based on how you will use it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 – Create a Dedicated Network for the DevBox
&lt;/h2&gt;

&lt;p&gt;I chose to create a small &lt;strong&gt;VPC with a /24 network&lt;/strong&gt;, which is just ideal for this case.  &lt;/p&gt;

&lt;p&gt;You can optionally add an &lt;strong&gt;S3 Private Gateway Endpoint&lt;/strong&gt; for no extra charge. This would be useful for copying files from authorized S3 buckets into your environment when needed.&lt;/p&gt;

&lt;p&gt;I chose a simple &lt;strong&gt;public subnet design&lt;/strong&gt; with a &lt;strong&gt;restricted instance security group&lt;/strong&gt; allowing &lt;strong&gt;SSH access only from my IP address&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0qowglvtb2414zppwey6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0qowglvtb2414zppwey6.png" width="800" height="990"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfm74pplgrkrg2m97zfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfm74pplgrkrg2m97zfw.png" width="800" height="1123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zq8hi8xphbqfgrv8v99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zq8hi8xphbqfgrv8v99.png" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswc2tvjw4u0y84m60pwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswc2tvjw4u0y84m60pwe.png" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 – Create the DevBox EC2 Instance
&lt;/h2&gt;

&lt;p&gt;You can go with the latest &lt;strong&gt;Amazon Linux AMI&lt;/strong&gt; or &lt;strong&gt;Ubuntu 24.04 LTS&lt;/strong&gt;, which I used in this setup.&lt;/p&gt;

&lt;p&gt;Restrict &lt;strong&gt;SSH access to your IP&lt;/strong&gt; in the security group for security.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplybmajln5gs6a8xrwng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplybmajln5gs6a8xrwng.png" width="800" height="690"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40h0r1pi0ihdcaln689q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40h0r1pi0ihdcaln689q.png" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzyasian7gjllxlcbofd6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzyasian7gjllxlcbofd6.png" width="800" height="1030"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkl8paibccnkiguibrzd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkl8paibccnkiguibrzd.png" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvv8b4jdst28ozqr10o5.png" width="800" height="1252"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Step 3 – Configure SSH Access in VS Code
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Right-click the left panel of your &lt;strong&gt;VS Code editor&lt;/strong&gt; and ensure the &lt;strong&gt;Remote Explorer&lt;/strong&gt; is checked.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffeiumykh165dxjw05chj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffeiumykh165dxjw05chj.png" width="550" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gzzs5gq3qkrcm0u7pmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gzzs5gq3qkrcm0u7pmi.png" width="162" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Right-click on &lt;strong&gt;SSH&lt;/strong&gt; and open the config file.
&lt;/li&gt;
&lt;li&gt;Edit the config file as shown below:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7flo9332ls8cf8cettl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7flo9332ls8cf8cettl.png" width="636" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User&lt;/strong&gt;: Varies depending on the AMI you use.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IdentityFile&lt;/strong&gt;: Points to the location of your key file.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HostName&lt;/strong&gt;: The remote server IP address.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7wo6wc4yl10ima4722o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7wo6wc4yl10ima4722o.png" width="800" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect in a &lt;strong&gt;new window&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rnpbb7nikp3lc05e02c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rnpbb7nikp3lc05e02c.png" width="734" height="152"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confirm the step by hitting the &lt;strong&gt;Enter&lt;/strong&gt; key. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0bzq2tnjovtropq93n9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0bzq2tnjovtropq93n9.png" width="800" height="144"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It should take a few seconds to connect and configure — and boom! You’re connected via SSH within VS Code, while utilizing &lt;strong&gt;cloud storage and networking&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Further Steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install your packages and set up your environment as needed.
&lt;/li&gt;
&lt;li&gt;Expand the storage as you grow.
&lt;/li&gt;
&lt;li&gt;Optionally add a &lt;strong&gt;second EBS volume&lt;/strong&gt; as the data/working volume.
&lt;/li&gt;
&lt;li&gt;Connect to an &lt;strong&gt;S3 bucket&lt;/strong&gt; within your account via the S3 Gateway.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Back up&lt;/strong&gt; the volume, stop, and/or terminate the instance as needed.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>architecture</category>
      <category>cloud</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Customize VPCs with CloudFormation Conditions</title>
      <dc:creator>Mawuli Denteh</dc:creator>
      <pubDate>Mon, 13 Jan 2025 03:29:22 +0000</pubDate>
      <link>https://dev.to/aws-builders/customizable-vpcs-with-cloudformation-conditions-2af7</link>
      <guid>https://dev.to/aws-builders/customizable-vpcs-with-cloudformation-conditions-2af7</guid>
      <description>&lt;p&gt;Using CloudFormation Conditions you can decide which resources to create/configure from your CloudFormation template. &lt;/p&gt;

&lt;p&gt;In this post, we are going to build a template that can create a VPC with private subnets and a NAT gateway or only public subnets depending on a parameter when creating the CloudFormation stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps to create and use Conditions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Define the input parameters you want your condition to evaluate.&lt;/li&gt;
&lt;li&gt;Define the condition by using the intrinsic condition functions. &lt;/li&gt;
&lt;li&gt;Declare the condition in resources or outputs you want to create. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's dive into the example!&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the parameter and condition
&lt;/h2&gt;

&lt;p&gt;In the first part of our template, we'll define our parameter and condition.&lt;/p&gt;

&lt;p&gt;We associate the &lt;em&gt;CreatePrivateResources&lt;/em&gt; condition with a value/option from our &lt;em&gt;CreateNatGateway&lt;/em&gt; parameter. This enables us to do what has been discussed in the intro above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Parameters:
  CreateNatGateway:
    Type: String
    Description: "Need a NAT Gateway?"
    AllowedValues:
      - yes
      - no
    Default: yes

Conditions:
  CreatePrivateResources: !Equals
    - !Ref CreateNatGateway
    - yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Define the public resources&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here, we will define our VPC, internet gateway, public subnets, routes and route tables. These resources will always be created. This is because they will not have any condition associated with them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: "10.0.0.0/16"
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-VPC"

  # Public Resources
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-InternetGateway"

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.1.0/24"
      MapPublicIpOnLaunch: true
      AvailabilityZone: !Select [0, !GetAZs ""]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PublicSubnet1"

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.2.0/24"
      MapPublicIpOnLaunch: true
      AvailabilityZone: !Select [1, !GetAZs ""]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PublicSubnet2"

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PublicRouteTable"

  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Use the condition&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We now apply our condition to selected resources which creates a private environment for us, i.e. NatGateway, private subnets and routes etc. If we choose no at the prompt, these will not get created.&lt;/p&gt;

&lt;p&gt;We also control the display of outputs using the same conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Private Resources
  NatGateway:
    Condition: CreatePrivateResources
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt EIPNatGateway.AllocationId
      SubnetId: !Ref PublicSubnet1
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-NatGateway"

  EIPNatGateway:
    Condition: CreatePrivateResources
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-EIPNatGateway"

  PrivateSubnet1:
    Condition: CreatePrivateResources
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.3.0/24"
      MapPublicIpOnLaunch: false
      AvailabilityZone: !Select [0, !GetAZs ""]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PrivateSubnet1"

  PrivateSubnet2:
    Condition: CreatePrivateResources
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.4.0/24"
      MapPublicIpOnLaunch: false
      AvailabilityZone: !Select [1, !GetAZs ""]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PrivateSubnet2"

  PrivateRouteTable:
    Condition: CreatePrivateResources
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PrivateRouteTable"

  PrivateRoute:
    Condition: CreatePrivateResources
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NatGateway

  PrivateSubnet1RouteTableAssociation:
    Condition: CreatePrivateResources
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnet2RouteTableAssociation:
    Condition: CreatePrivateResources
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable

Outputs:
  VPCId:
    Description: "VPC ID"
    Value: !Ref VPC
  PublicSubnet1Id:
    Description: "Public Subnet 1 ID"
    Value: !Ref PublicSubnet1
  PublicSubnet2Id:
    Description: "Public Subnet 2 ID"
    Value: !Ref PublicSubnet2
  PrivateSubnet1Id:
    Condition: CreatePrivateResources
    Description: "Private Subnet 1 ID"
    Value: !Ref PrivateSubnet1
  PrivateSubnet2Id:
    Condition: CreatePrivateResources
    Description: "Private Subnet 2 ID"
    Value: !Ref PrivateSubnet2
  NatGatewayId:
    Condition: CreatePrivateResources
    Description: "NAT Gateway ID"
    Value: !Ref NatGateway

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now customize your VPC creation just by changing a parameter. &lt;br&gt;
Thanks for reading. Happy Building!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>vpc</category>
      <category>cloudformation</category>
      <category>iac</category>
    </item>
    <item>
      <title>Create a load-balanced web server with auto-scaling</title>
      <dc:creator>Mawuli Denteh</dc:creator>
      <pubDate>Wed, 06 Mar 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/create-a-load-balanced-web-server-with-auto-scaling-6d</link>
      <guid>https://dev.to/aws-builders/create-a-load-balanced-web-server-with-auto-scaling-6d</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This tutorial walks you through the process of creating web servers, managed by an auto scaling group. The auto scaling group uses a launch template to create the servers. The auto scaling group launches the servers into a target group. An internet-facing load balancer directs traffic to the target group.&lt;/p&gt;



&lt;h2&gt;
  
  
  Architecture Diagram
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsj06xqv2yftpysyi2ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsj06xqv2yftpysyi2ik.png" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  1. Create a VPC
&lt;/h2&gt;

&lt;p&gt;A VPC is an isolated, private network you can create to run your workloads. You have complete control over your VPC when you create one.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on &lt;a href="https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#CreateVpc:createMode=vpcWithResources" rel="noopener noreferrer"&gt;Create VPC&lt;/a&gt; from the VPC Dashboard to create a new VPC.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;VPC and more&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter a name under &lt;strong&gt;Auto-generate&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose a &lt;strong&gt;10.0.0.0/16&lt;/strong&gt; IPV4 Cidr block.&lt;/li&gt;
&lt;li&gt;Number of Availability Zones (AZs) = 2.&lt;/li&gt;
&lt;li&gt;Number of public subnets = 2.&lt;/li&gt;
&lt;li&gt;Number of private subnets = 0.&lt;/li&gt;
&lt;li&gt;NAT gateways ($): None.&lt;/li&gt;
&lt;li&gt;VPC endpoints = None.&lt;/li&gt;
&lt;li&gt;Leave all other settings as default.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create VPC&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/9MKsavNn_pQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;



&lt;h2&gt;
  
  
  2. Create a Launch Template
&lt;/h2&gt;

&lt;p&gt;The launch template will serve as the blueprint for creating the exact type of server we need to meet our web server demands. A launch template can be modified to create new versions when you need to change a configuration.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on &lt;a href="https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#CreateTemplate:" rel="noopener noreferrer"&gt;Create launch template&lt;/a&gt; from the EC2 console to create a new launch template.&lt;/li&gt;
&lt;li&gt;Launch template name - required.&lt;/li&gt;
&lt;li&gt;Check the &lt;strong&gt;Provide guidance to help me set up a template that I can use with EC2 Auto Scaling&lt;/strong&gt; box.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Application and OS Images (Amazon Machine Image) - required&lt;/strong&gt;, choose &lt;strong&gt;Amazon Linux 2023 AMI&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Instance type = &lt;strong&gt;t2.micro&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Key pair - Proceed without a keypair.&lt;/li&gt;
&lt;li&gt;Subnet - &lt;strong&gt;Don't include in launch template&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Create security group.&lt;/li&gt;
&lt;li&gt;Allow HTTP traffic from 0.0.0.0/0 (Ignore the warning about security group. We will edit it later).&lt;/li&gt;
&lt;li&gt;VPC - Select the VPC you created.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Advanced network configuration&lt;/strong&gt;, choose &lt;strong&gt;Enable&lt;/strong&gt; under &lt;strong&gt;Auto-assign public IP&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Storage&lt;/strong&gt;, leave all other configuration as default and choose &lt;strong&gt;"gp3"&lt;/strong&gt; for &lt;strong&gt;Volume type&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Resource tags: optional.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Advanced details&lt;/strong&gt;, scroll down to the &lt;strong&gt;User data&lt;/strong&gt; section and enter the following lines of code exactly as shown:&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;span class="c"&gt;# Install packages and Nginx server&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;service nginx status

&lt;span class="c"&gt;# Query the instance metadata service&lt;/span&gt;
&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="s2"&gt;"http://169.254.169.254/latest/api/token"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-aws-ec2-metadata-token-ttl-seconds: 21600"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Fetch the hostname&lt;/span&gt;
&lt;span class="nv"&gt;HOSTNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-aws-ec2-metadata-token: &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; http://169.254.169.254/latest/meta-data/hostname&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Add web server content&lt;/span&gt;
&lt;span class="nb"&gt;sudo tee&lt;/span&gt; /var/www/html/index.nginx-debian.html &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;title&amp;gt;WebServer&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            padding: 0;
            text-align: center;
        }
        .container {
            max-width: 600px;
            margin: 0 auto;
            border: 1px solid #ccc;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        h1 {
            color: #333;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div class="container"&amp;gt;
        &amp;lt;h1&amp;gt;Hello from &lt;/span&gt;&lt;span class="nv"&gt;$HOSTNAME&lt;/span&gt;&lt;span class="sh"&gt;&amp;lt;/h1&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Configure stress for autoscaling&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; stress
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; /home/ubuntu/start_stress.sh
#!/bin/bash
sleep 300
vcpus=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
workers=&lt;/span&gt;&lt;span class="nv"&gt;$vcpus&lt;/span&gt;&lt;span class="sh"&gt;
stress --cpu "&lt;/span&gt;&lt;span class="nv"&gt;$workers&lt;/span&gt;&lt;span class="sh"&gt;" --timeout 1200
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /home/ubuntu/start_stress.sh
&lt;span class="nb"&gt;nohup&lt;/span&gt; /home/ubuntu/start_stress.sh &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /home/ubuntu/start_stress.log 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;span class="nb"&gt;sudo &lt;/span&gt;service nginx restart

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/J_a9zdVQRmo"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;



&lt;h2&gt;
  
  
  3. Create Target Group
&lt;/h2&gt;

&lt;p&gt;A target group will route requests to the web servers we create. Our load balancer will need this target group to know what set of servers to distribute traffic to. Our auto scaling group will also be associated with this target group so it launches our servers into the target group.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on &lt;a href="https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#CreateTargetGroup:" rel="noopener noreferrer"&gt;Create target group&lt;/a&gt; from the EC2 console to create a target group.&lt;/li&gt;
&lt;li&gt;Choose a target type: &lt;strong&gt;Instances&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Target group name: Enter a name.&lt;/li&gt;
&lt;li&gt;Protocol: &lt;strong&gt;HTTP&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Port: &lt;strong&gt;80&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;VPC: Select the VPC you created.&lt;/li&gt;
&lt;li&gt;Leave every other value on this page as default. &lt;strong&gt;Next&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Register Targets: Leave as is.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create target group&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/d5Uzm132PpM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;



&lt;h2&gt;
  
  
  4. Create Load Balancer
&lt;/h2&gt;

&lt;p&gt;An application load balancer acts as the entry point for traffic to our web servers. Instead of allowing users to access our application directly, we will use the load balancer to distribute traffic equally among our autoscaling group of web servers. This is better for load management, security and reliability of our application.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on &lt;a href="https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#SelectCreateELBWizard:" rel="noopener noreferrer"&gt;Create load balancer&lt;/a&gt; from the EC2 console to create a load balancer&lt;/li&gt;
&lt;li&gt;Type: &lt;strong&gt;Application Load Balancer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Scheme: &lt;strong&gt;Internet-facing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;IP address type: &lt;strong&gt;IPV4&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;VPC: Select the VPC you created.&lt;/li&gt;
&lt;li&gt;Mappings: Check the box beside the two AZs listed.&lt;/li&gt;
&lt;li&gt;Subnet: For each AZ selected, choose the public subnet in the dropdown menu.&lt;/li&gt;
&lt;li&gt;At this point, go to the Security groups console and create a new security group for the load balancer. The inbound rule should allow HTTP traffic from anywhere.&lt;/li&gt;
&lt;li&gt;Select this security group as the load balancer security group.&lt;/li&gt;
&lt;li&gt;Listeners and routing: Leave protocol and port as &lt;strong&gt;HTTP:80&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;Select the target group you created as target group.&lt;/li&gt;
&lt;li&gt;Leave every other config as default and click &lt;strong&gt;Create load balancer&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/JVyPOaC1QII"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;



&lt;h2&gt;
  
  
  5. Create Auto Scaling Group
&lt;/h2&gt;

&lt;p&gt;The auto scaling group configures and controls how your application scales automatically in response to varying traffic situations.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on &lt;a href="https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#CreateAutoScalingGroup:" rel="noopener noreferrer"&gt;Create Auto Scaling group&lt;/a&gt; from the EC2 console to create an auto scaling group.&lt;/li&gt;
&lt;li&gt;Enter a name.&lt;/li&gt;
&lt;li&gt;Choose the launch template you created. Click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select your webserver VPC created from the VPC step.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Availability Zones and subnets&lt;/strong&gt;, select the two public subnets in your VPC, in different AZs. Click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;NB:&lt;/strong&gt; Note that you can use the auto scaling group to override your instance type config from the launch template*.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Under &lt;strong&gt;Load balancing&lt;/strong&gt;, choose the option &lt;strong&gt;Attach to an existing load balancer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Choose from your load balancer target groups&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select the target group you created.&lt;/li&gt;
&lt;li&gt;Select VPC Lattice service to attach: &lt;strong&gt;No VPC Lattice service&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Additional health check types - optional: &lt;strong&gt;Turn on Elastic Load Balancing health checks&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Leave every other config as default. &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Group size: Desired: &lt;strong&gt;2&lt;/strong&gt;, Minimum: &lt;strong&gt;1&lt;/strong&gt;, Maximum: &lt;strong&gt;4&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Scaling policies: &lt;strong&gt;Target Tracking Policy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Metric type: &lt;strong&gt;Average CPU Utilization&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Target Value: &lt;strong&gt;50%&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create Auto Scaling Group&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/miOEZZcFtAI"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Once you successfully create your autoscaling group, you should see two new instances in the EC2 console. This is because we specified a desired count of 2. Also note that they are automatically placed one in each AZ to support high availability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fik0v7svx5xpe8g6v45tj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fik0v7svx5xpe8g6v45tj.png" width="800" height="132"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Restrict web traffic to servers
&lt;/h2&gt;

&lt;p&gt;With the current design, users can directly access our web server using its IP address. We don't want that. That is why we created a load balancer.&lt;/p&gt;

&lt;p&gt;To ensure all incoming HTTP traffic goes through the load balancer, we will update the webserver security group to accept HTTP traffic only from our application load balancer security group.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;strong&gt;autoscale-webserver-sg&lt;/strong&gt; security group and click on &lt;strong&gt;Edit inbound rules&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Delete the existing HTTP rule.&lt;/li&gt;
&lt;li&gt;Add a new HTTP rule. In the &lt;strong&gt;Source&lt;/strong&gt; box, scroll down to select the security group of the load balancer. &lt;strong&gt;Save rules&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You have successfully restricted traffic going to the servers to the load balancer.&lt;/li&gt;
&lt;li&gt;You should no longer be able to access your web server using the server IPs or DNS names. You should now be able to use the load balancer DNS name to access the servers. Test this out.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgenuiea2j6qbr0a5t9qe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgenuiea2j6qbr0a5t9qe.png" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Observations
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;From the details tab of the load balancer, copy the DNS name and paste in a new tab. Refresh the tab and note the changing hostnames with every refresh. That's the load balancer alternating traffic between its target web servers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd27cfdmch0nybz.cloudfront.net%2Fblog-demos%2Fautoscaling%2Fvideos%2Fautoscaling-alb-demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd27cfdmch0nybz.cloudfront.net%2Fblog-demos%2Fautoscaling%2Fvideos%2Fautoscaling-alb-demo.gif" alt="ALB at work" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;ol&gt;
&lt;li&gt;After launching the desired number of instances, a bash script will run in the background to increase CPU utilization to 50%. This will trigger a scale out action.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This should lead to a maximum number of 4 instances being available to serve web traffic.&lt;/p&gt;

&lt;p&gt;When the script stops running, a scale in action should equally be triggered to reduce the instances back to the desired number.&lt;/p&gt;

&lt;p&gt;It takes about an hour to observe this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi08vynp7jk9b0vcrb6aw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi08vynp7jk9b0vcrb6aw.png" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You have built a load-balanced and highly available web application that auto-scales based on a target of CPU utilization.&lt;/p&gt;

&lt;p&gt;Delete the autoscaling group and load balancer after your tests to prevent unwanted charges.&lt;/p&gt;

&lt;p&gt;If you made it this far, here's a little reward:&lt;/p&gt;

&lt;p&gt;The CloudFormation stack below will deploy exactly what you have built in the demo. Try it out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mawulident/aws-autoscaling/blob/main/AutoScalingWebserver.yaml" rel="noopener noreferrer"&gt;Download IAC template&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
