<?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: Vinh Le</title>
    <description>The latest articles on DEV Community by Vinh Le (@vinhle).</description>
    <link>https://dev.to/vinhle</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%2F884289%2F9c9341a9-1bed-48c9-a98a-f5e636734a65.png</url>
      <title>DEV Community: Vinh Le</title>
      <link>https://dev.to/vinhle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vinhle"/>
    <language>en</language>
    <item>
      <title>Multiple SSH keys for different Git accounts</title>
      <dc:creator>Vinh Le</dc:creator>
      <pubDate>Sun, 11 Sep 2022 09:54:35 +0000</pubDate>
      <link>https://dev.to/vinhle/multiple-ssh-keys-for-different-accounts-16af</link>
      <guid>https://dev.to/vinhle/multiple-ssh-keys-for-different-accounts-16af</guid>
      <description>&lt;h2&gt;
  
  
  🗒️ Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Before SSH Keys Setup&lt;/li&gt;
&lt;li&gt;Connecting to GitLab with SSH&lt;/li&gt;
&lt;li&gt;Connecting to GitHub with SSH&lt;/li&gt;
&lt;li&gt;A Better Keys Organization&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Before SSH Keys Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Checking for existing SSH keys file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; ~/.ssh
id_rsa  id_rsa.pub  known_hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Confirm active public SSH keys (&lt;code&gt;*.pub&lt;/code&gt;) in ssh-agent
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ssh-add &lt;span class="nt"&gt;-L&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Remove all old keys
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ~/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Connecting to GitLab with SSH
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;: Generate an SSH key pair
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;your_email_01&amp;gt;@gmail.com"&lt;/span&gt;
Generating public/private ed25519 key pair.
Enter file &lt;span class="k"&gt;in &lt;/span&gt;which to save the key &lt;span class="o"&gt;(&lt;/span&gt;/home/&amp;lt;user&amp;gt;/.ssh/id_ed25519&lt;span class="o"&gt;)&lt;/span&gt;: /home/&amp;lt;user&amp;gt;/.ssh/id_ed25519_gitlab
Enter passphrase &lt;span class="o"&gt;(&lt;/span&gt;empty &lt;span class="k"&gt;for &lt;/span&gt;no passphrase&lt;span class="o"&gt;)&lt;/span&gt;:
Enter same passphrase again:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 2&lt;/strong&gt;: Add an SSH key to your GitLab account
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_ed25519_gitlab.pub
&lt;span class="c"&gt;# or&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;xclip &lt;span class="nt"&gt;-sel&lt;/span&gt; clip &amp;lt; ~/.ssh/id_ed25519_gitlab.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the contents of your public key file by manually or a script. Then coming to &lt;em&gt;GitLab &amp;gt; Preferences &amp;gt; SSH Keys&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 3&lt;/strong&gt;: Verify that you can connect
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ssh &lt;span class="nt"&gt;-T&lt;/span&gt; git@gitlab.com
...
Are you sure you want to &lt;span class="k"&gt;continue &lt;/span&gt;connecting &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;yes&lt;/span&gt;/no/[fingerprint]&lt;span class="o"&gt;)&lt;/span&gt;? &lt;span class="nb"&gt;yes
&lt;/span&gt;Welcome to GitLab, &amp;lt;user_name&amp;gt;!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Connecting to GitHub with SSH
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;: Generate an SSH key pair
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;your_email_02&amp;gt;@gmail.com"&lt;/span&gt;
Generating public/private ed25519 key pair.
Enter file &lt;span class="k"&gt;in &lt;/span&gt;which to save the key &lt;span class="o"&gt;(&lt;/span&gt;/home/&amp;lt;user&amp;gt;/.ssh/id_ed25519&lt;span class="o"&gt;)&lt;/span&gt;: /home/&amp;lt;user&amp;gt;/.ssh/id_ed25519_github
Enter passphrase &lt;span class="o"&gt;(&lt;/span&gt;empty &lt;span class="k"&gt;for &lt;/span&gt;no passphrase&lt;span class="o"&gt;)&lt;/span&gt;:
Enter same passphrase again:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 2&lt;/strong&gt;: Add an SSH key to your GitLab account
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_ed25519_github.pub
&lt;span class="c"&gt;# or&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;xclip &lt;span class="nt"&gt;-sel&lt;/span&gt; clip &amp;lt; ~/.ssh/id_ed25519_github.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the contents of your public key file by manually or a script. Then coming to &lt;em&gt;GitHub &amp;gt; Settings &amp;gt;  SSH and GPG keys&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 3&lt;/strong&gt;: Verify that you can connect
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ssh &lt;span class="nt"&gt;-T&lt;/span&gt; git@github.com
...
Are you sure you want to &lt;span class="k"&gt;continue &lt;/span&gt;connecting &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;yes&lt;/span&gt;/no/[fingerprint]&lt;span class="o"&gt;)&lt;/span&gt;? &lt;span class="nb"&gt;yes
&lt;/span&gt;Hi &amp;lt;user_name&amp;gt;! You&lt;span class="s1"&gt;'ve successfully authenticated, but GitHub does not provide shell access.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. A Better Keys Organization
&lt;/h2&gt;

&lt;p&gt;For more information on these settings, see the &lt;a href="https://man.openbsd.org/ssh_config"&gt;man ssh_config&lt;/a&gt;&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.ssh/
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;config
&lt;span class="nv"&gt;$ &lt;/span&gt;vi config
&lt;span class="c"&gt;# GitLab&lt;/span&gt;
Host gitlab.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/id_ed25519_gitlab

&lt;span class="c"&gt;# GitHub&lt;/span&gt;
Host github.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/id_ed25519_github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>git</category>
      <category>ssh</category>
      <category>github</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>AWS CloudFormation - Separately Manage Network and Server Stacks by Cross Stacks</title>
      <dc:creator>Vinh Le</dc:creator>
      <pubDate>Sun, 21 Aug 2022 16:33:41 +0000</pubDate>
      <link>https://dev.to/vinhle/hands-on-aws-cloudformation-separately-manage-network-and-server-stacks-by-cross-stacks-4km4</link>
      <guid>https://dev.to/vinhle/hands-on-aws-cloudformation-separately-manage-network-and-server-stacks-by-cross-stacks-4km4</guid>
      <description>&lt;h2&gt;
  
  
  🗒️ Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;AWS CloudFormation 101&lt;/li&gt;
&lt;li&gt;One key pair f&lt;/li&gt;
&lt;li&gt;Hands-on Lab: Separately Manage Network and Server Stacks by Cross Stacks&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. AWS CloudFormation 101
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1. Infrastructure as Code (IaC)
&lt;/h3&gt;

&lt;p&gt;Treating infrastructure in the same way as developers treat code is one of the most fundamental principles of DevOps.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Infrastructure as code (IaC)&lt;/strong&gt; means provisioning, configuring and managing your infrastructure resources using code and templates. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1.2. AWS CloudFormation
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;AWS CloudFormation is a service speeding up cloud provisioning with infrastructure as code&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AWS resources and infrastructure architecture are modeled and described in CloudFormation templates written in JSON or &lt;strong&gt;YAML&lt;/strong&gt; (recommended) formatted text file. After that CloudFormation takes care of provisioning and configuring those resources for you.&lt;/p&gt;

&lt;p&gt;The CloudFormation workflow for creating stacks as the below diagram&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd1.awsstatic.com%2FProducts%2Fproduct-name%2Fdiagrams%2Fproduct-page-diagram_CloudFormation.ad3a4c93b4fdd3366da3da0de4fb084d89a5d761.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd1.awsstatic.com%2FProducts%2Fproduct-name%2Fdiagrams%2Fproduct-page-diagram_CloudFormation.ad3a4c93b4fdd3366da3da0de4fb084d89a5d761.png" alt="CloudFormation workflow"&gt;&lt;/a&gt; &lt;br&gt;
CloudFormation Workflow (source: &lt;a href="https://aws.amazon.com/cloudformation/" rel="noopener noreferrer"&gt;https://aws.amazon.com/cloudformation/&lt;/a&gt;)&lt;/p&gt;
&lt;h2&gt;
  
  
  2. CloudFormation Templates Structure
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Resource (mandatory): declare the AWS resources&lt;/li&gt;
&lt;li&gt;Parameters (optional): input custom values to template each time creating/updating a stack, using with &lt;code&gt;!Ref &amp;lt;parameter&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Mapping (optional): map a key to a specific value, using with &lt;code&gt;!FindInMap [ &amp;lt;map_name&amp;gt;, &amp;lt;top_key&amp;gt;, &amp;lt;second_key&amp;gt; ]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Condition (optional): control the creation of resources or outputs based on a condition&lt;/li&gt;
&lt;li&gt;Output (optional): return output values of stack&lt;/li&gt;
&lt;li&gt;Cross-stack: separate templates and refer values from different stacks, using with &lt;code&gt;Export&lt;/code&gt; from one stack and &lt;code&gt;!ImportValue &amp;lt;export_name&amp;gt;&lt;/code&gt; from other stacks&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  3. Hands-on Lab: Separately Manage Network and Server Stacks by Cross Stacks
&lt;/h2&gt;

&lt;p&gt;Assume that we are developing a simple web application with the following architecture&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One VPC, one public subnet, one EC2 instance&lt;/li&gt;
&lt;li&gt;One security group opening in port 80 (for HTTP from anywhere)
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd1j7zd7t38gahw.cloudfront.net%2Fdev.to%2FAWS_CloudFormation_CrossStack.jpg" alt="Application Architecture"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Separating our infrastructure into 2 templates may help us manage them easier.&lt;/p&gt;
&lt;h3&gt;
  
  
  3.1. LabNetworkStack
&lt;/h3&gt;

&lt;p&gt;The content of &lt;code&gt;lab_network_cfn.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;This template manages network components&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;ApplicationName&lt;/span&gt;&lt;span class="pi"&gt;:&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;An application name that is prefixed to resource names&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;lab&lt;/span&gt;
  &lt;span class="na"&gt;VpcCidr&lt;/span&gt;&lt;span class="pi"&gt;:&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;The IP range (CIDR notation) for VPC in form x.x.x.x/16-28&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;AllowedPattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;/(1[6-9]|2[0-8]))$"&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.192.0.0/16&lt;/span&gt;
  &lt;span class="na"&gt;PublicSubnetCidr&lt;/span&gt;&lt;span class="pi"&gt;:&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;The IP range (CIDR notation) for public subnet in form x.x.x.x/16-28&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;AllowedPattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;/(1[6-9]|2[0-8]))$"&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.192.10.0/24&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Vpc&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;AWS::EC2::VPC&lt;/span&gt;
    &lt;span class="na"&gt;Properties&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="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;VpcCidr&lt;/span&gt;
      &lt;span class="na"&gt;EnableDnsSupport&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;EnableDnsHostnames&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;Tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Name&lt;/span&gt;
          &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${ApplicationName}-vpc'&lt;/span&gt;
  &lt;span class="na"&gt;PublicSubnet&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;AWS::EC2::Subnet&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;VpcId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;Vpc&lt;/span&gt;
      &lt;span class="na"&gt;CidrBlock&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;PublicSubnetCidr&lt;/span&gt;
      &lt;span class="na"&gt;MapPublicIpOnLaunch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;Tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Name&lt;/span&gt;
          &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${ApplicationName}-public-subnet'&lt;/span&gt;
  &lt;span class="na"&gt;InternetGateway&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;AWS::EC2::InternetGateway&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Name&lt;/span&gt;
          &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${ApplicationName}-igw'&lt;/span&gt;
  &lt;span class="na"&gt;InternetGatewayAttachment&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;AWS::EC2::VPCGatewayAttachment&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;InternetGatewayId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;InternetGateway&lt;/span&gt;
      &lt;span class="na"&gt;VpcId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;Vpc&lt;/span&gt;
  &lt;span class="na"&gt;PublicRouteTable&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;AWS::EC2::RouteTable&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;VpcId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;Vpc&lt;/span&gt;
      &lt;span class="na"&gt;Tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Name&lt;/span&gt;
          &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${ApplicationName}-rtb'&lt;/span&gt;
  &lt;span class="na"&gt;DefaultPublicRoute&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;AWS::EC2::Route&lt;/span&gt;
    &lt;span class="na"&gt;DependsOn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;InternetGatewayAttachment&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;RouteTableId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;PublicRouteTable&lt;/span&gt;
      &lt;span class="na"&gt;DestinationCidrBlock&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0/0&lt;/span&gt;
      &lt;span class="na"&gt;GatewayId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;InternetGateway&lt;/span&gt;
  &lt;span class="na"&gt;PublicSubnetRouteTableAssociation&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;AWS::EC2::SubnetRouteTableAssociation&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;RouteTableId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;PublicRouteTable&lt;/span&gt;
      &lt;span class="na"&gt;SubnetId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet&lt;/span&gt;

&lt;span class="na"&gt;Outputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;VpcId&lt;/span&gt;&lt;span class="pi"&gt;:&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;The VPC ID of lab application&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;Vpc&lt;/span&gt;
    &lt;span class="na"&gt;Export&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${AWS::StackName}-VpcId'&lt;/span&gt;
  &lt;span class="na"&gt;SubnetId&lt;/span&gt;&lt;span class="pi"&gt;:&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;The Subnet ID of lab application&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet&lt;/span&gt;
    &lt;span class="na"&gt;Export&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${AWS::StackName}-PublicSubnetId'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template can be deployed with AWS CLI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;lab_network_cfn.yml s3://&amp;lt;your_bucket&amp;gt;
aws cloudformation create-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; LabNetworkStack &lt;span class="nt"&gt;--template-url&lt;/span&gt; https://&amp;lt;your_bucket&amp;gt;.s3.&amp;lt;your_region&amp;gt;.amazonaws.com/lab_network_cfn.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2. LabServerStack
&lt;/h3&gt;

&lt;p&gt;The content of &lt;code&gt;lab_server_cfn.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;This template manages servers components&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;ApplicationName&lt;/span&gt;&lt;span class="pi"&gt;:&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;An application name that is prefixed to resource names&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;lab&lt;/span&gt;
  &lt;span class="na"&gt;Landscape&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;develop&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;develop&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
  &lt;span class="na"&gt;NetworkStackName&lt;/span&gt;&lt;span class="pi"&gt;:&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;The name of Network CloudFormation stack&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;LabNetworkStack&lt;/span&gt;

&lt;span class="na"&gt;Mappings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;RegionMap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ap-southeast-1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;AMI&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ami-02ee763250491e04a&lt;/span&gt;
    &lt;span class="na"&gt;ap-southeast-2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;AMI&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ami-0e040c48614ad1327&lt;/span&gt;

&lt;span class="na"&gt;Conditions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;IsProduction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Equals&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="nv"&gt;Landscape&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;SecurityGroup&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;AWS::EC2::SecurityGroup&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;GroupDescription&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Security&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;group&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;${ApplicationName}&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;instances'&lt;/span&gt;
      &lt;span class="na"&gt;SecurityGroupIngress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;IpProtocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tcp&lt;/span&gt;
          &lt;span class="na"&gt;FromPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
          &lt;span class="na"&gt;ToPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
          &lt;span class="na"&gt;CidrIp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0/0&lt;/span&gt;
      &lt;span class="na"&gt;VpcId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!ImportValue&lt;/span&gt;
        &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Fn::Sub'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${NetworkStackName}-VpcId'&lt;/span&gt;
      &lt;span class="na"&gt;Tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Name&lt;/span&gt;
          &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${ApplicationName}-srg'&lt;/span&gt;
  &lt;span class="na"&gt;Ec2Instance&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;AWS::EC2::Instance&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
      &lt;span class="na"&gt;ImageId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!FindInMap&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;RegionMap&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AWS::Region'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;AMI&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;InstanceType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!If&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;IsProduction&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;t2.small&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;t2.micro&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt; 
      &lt;span class="na"&gt;KeyName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your_key_name&lt;/span&gt;
      &lt;span class="na"&gt;SubnetId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!ImportValue&lt;/span&gt;
        &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Fn::Sub'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${NetworkStackName}-PublicSubnetId'&lt;/span&gt;
      &lt;span class="na"&gt;SecurityGroupIds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;SecurityGroup&lt;/span&gt;
      &lt;span class="na"&gt;BlockDeviceMappings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;DeviceName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/dev/sda1"&lt;/span&gt;
        &lt;span class="na"&gt;Ebs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;VolumeSize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
          &lt;span class="na"&gt;VolumeType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gp2&lt;/span&gt;
          &lt;span class="na"&gt;Encrypted&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;UserData&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fn::Base64"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
          &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;#!/bin/bash&lt;/span&gt;
            &lt;span class="s"&gt;apt update&lt;/span&gt;
            &lt;span class="s"&gt;apt install apache2 -y&lt;/span&gt;
      &lt;span class="na"&gt;Tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Name&lt;/span&gt;
          &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${ApplicationName}-ec2'&lt;/span&gt;

&lt;span class="na"&gt;Outputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;InstanceIp&lt;/span&gt;&lt;span class="pi"&gt;:&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;The IP address of instance&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt; &lt;span class="s"&gt;Ec2Instance.PublicIp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template can be deployed with AWS CLI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;lab_server_cfn.yml s3://&amp;lt;your_bucket&amp;gt;
aws cloudformation create-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; LabServerStack &lt;span class="nt"&gt;--template-url&lt;/span&gt; https://&amp;lt;your_bucket&amp;gt;.s3.&amp;lt;your_region&amp;gt;.amazonaws.com/lab_server_cfn.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Confirmation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm the status of stacks are all &lt;code&gt;CREATE_COMPLETE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Confirm the default Ubuntu Apache web page &lt;code&gt;http://your_server_ip&lt;/code&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd1j7zd7t38gahw.cloudfront.net%2Fdev.to%2FCloudFormation_Ec2_DefaultPage.png" alt="EC2 Apache default page"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.3. Clean resources
&lt;/h3&gt;

&lt;p&gt;The stacks can be deleted by consoles or AWS CLI in the following order&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudformation delete-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; LabServerStack
aws cloudformation delete-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; LabNetworkStack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>cloudformation</category>
    </item>
    <item>
      <title>AWS CDK in Python - Schedule Lambda Functions</title>
      <dc:creator>Vinh Le</dc:creator>
      <pubDate>Wed, 29 Jun 2022 05:06:32 +0000</pubDate>
      <link>https://dev.to/vinhle/-develop-a-schedule-app-aws-cdk-with-python-part-1-4nbi</link>
      <guid>https://dev.to/vinhle/-develop-a-schedule-app-aws-cdk-with-python-part-1-4nbi</guid>
      <description>&lt;h2&gt;
  
  
  🗒️ Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;AWS CDK 101&lt;/li&gt;
&lt;li&gt;CDK Installation&lt;/li&gt;
&lt;li&gt;Hands-on Lab: Schedule Lambda Functions with AWS CDK in Python&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. AWS CDK 101
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1. Infrastructure as Code (IaC)
&lt;/h3&gt;

&lt;p&gt;Treating infrastructure in the same way as developers treat code is one of the most fundamental principles of DevOps.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Infrastructure as code (IaC)&lt;/strong&gt; means provisioning, configuring and managing your infrastructure resources using code and templates. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1.2. AWS CDK
&lt;/h3&gt;

&lt;p&gt;CloudFormation templates are used to define our application infrastructure. However, thanks to AWS CDK, the full power of a programming language can be leveraged to describe our infrastructure.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AWS CDK&lt;/strong&gt; is a framework for defining cloud infrastructure in code and provisioning it through AWS CloudFormation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1.3. AWS CDK Basic Concepts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Supported languages: TypeScript, JavaScript, Python, Java, C#/.Net and Go&lt;/li&gt;
&lt;li&gt;AWS CDK App: an application written in a supported language&lt;/li&gt;
&lt;li&gt;AWS CDK Stack: the unit of deployment in the AWS CDK, equivalent to AWS CloudFormation&lt;/li&gt;
&lt;li&gt;AWS CDK Constructs: the basic building blocks, represents a "cloud component"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P1kfdbro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.aws.amazon.com/cdk/v2/guide/images/AppStacks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P1kfdbro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.aws.amazon.com/cdk/v2/guide/images/AppStacks.png" alt="CDK App Structure" width="774" height="576"&gt;&lt;/a&gt; &lt;br&gt;
CDK App Structure (source: &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/images/AppStacks.png"&gt;https://docs.aws.amazon.com/cdk/v2/guide/images/AppStacks.png&lt;/a&gt;)&lt;/p&gt;
&lt;h2&gt;
  
  
  2. CDK Installation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install Node.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS CDK uses Node.js as its back-end regardless of the programming language you use, so &lt;code&gt;nodejs&lt;/code&gt; is required.&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nodejs
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; aws-cdk
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; cdk &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install &lt;code&gt;virtualenv&lt;/code&gt; package
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your programming language is &lt;code&gt;Python&lt;/code&gt;, using a virtual environment is recommended.&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="o"&gt;&amp;gt;&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;virtualenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Configure your AWS credentials
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS credentials also need to be configured in your local development environment, so that CDK CLI can communicate with AWS.&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="o"&gt;&amp;gt;&lt;/span&gt; aws configure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Hands-on Lab: Schedule Lambda Functions with AWS CDK in Python
&lt;/h2&gt;

&lt;p&gt;This tutorial shows how to use AWS CDK to build our first application, which is a AWS Lambda function on a schedule ⏰.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UbHipM4b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d1j7zd7t38gahw.cloudfront.net/dev.to/AWS_CDK_ScheduleLambda.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UbHipM4b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d1j7zd7t38gahw.cloudfront.net/dev.to/AWS_CDK_ScheduleLambda.jpg" alt="Schedule Lambda Functions Architecture" width="880" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;: Initialize the app using the cdk init command
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir &lt;/span&gt;ScheduleLambda
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;ScheduleLambda
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; cdk init app &lt;span class="nt"&gt;--language&lt;/span&gt; python
...
Executing Creating virtualenv...
✅ All &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note that &lt;code&gt;cdk init&lt;/code&gt; cannot be run in a non-empty directory! &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 2&lt;/strong&gt;: Activate the app's Python virtual environment and install dependencies
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Only in the first time, &lt;strong&gt;Bootstrapping&lt;/strong&gt; is required to provision resources that AWS CDK needs to perform the deployment, such as S3 bucket and IAM roles.&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="o"&gt;&amp;gt;&lt;/span&gt; cdk bootstrap aws://&amp;lt;your_account_id&amp;gt;/&amp;lt;your_region&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1HIsVibc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d1j7zd7t38gahw.cloudfront.net/dev.to/CDK_CDKToolkit_Stack.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1HIsVibc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d1j7zd7t38gahw.cloudfront.net/dev.to/CDK_CDKToolkit_Stack.png" alt="CDKToolkit Stack" width="619" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 3&lt;/strong&gt;: Add file &lt;code&gt;lambda/lambda-handler.py&lt;/code&gt; with the below content
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This is the Schedule Lambda Function's log"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'time'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that cdk prepares a virtual environment for us.&lt;br&gt;
The structure of our application is as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── app.py
├── cdk.json
├── lambda
│   └── lambda-handler.py
├── README.md
├── requirements-dev.txt
├── requirements.txt
├── schedule_lambda
│   ├── __init__.py
│   └── schedule_lambda_stack.py
├── source.bat
└── tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 4&lt;/strong&gt;: Update the content of &lt;code&gt;schedule_lambda_stack.py&lt;/code&gt; as the following
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;aws_cdk&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;aws_lambda&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;aws_events&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;aws_events_targets&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;constructs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Construct&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ScheduleLambdaStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;construct_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;construct_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# The code that defines your stack goes here
&lt;/span&gt;        &lt;span class="n"&gt;schedule_lambda&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aws_lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;'ScheduleLambda'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'lambda-handler.handler'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws_lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PYTHON_3_9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws_lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_asset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'lambda'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;schedule_lambda_rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aws_events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"ScheduleLambdaRule"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;schedule&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws_events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schedule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;schedule_lambda_rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aws_events_targets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LambdaFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;schedule_lambda&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 5&lt;/strong&gt;: Synthesize an AWS CloudFormation template
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; cdk synth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 6&lt;/strong&gt;: Deploying the stack
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; cdk deploy
...
Do you wish to deploy these changes &lt;span class="o"&gt;(&lt;/span&gt;y/n&lt;span class="o"&gt;)&lt;/span&gt;? y
...
 ✅  ScheduleLambdaStack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Step 7&lt;/strong&gt;: Confirm deployment in CloudFormation console&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FQuWwqHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d1j7zd7t38gahw.cloudfront.net/dev.to/CDK_ScheduleLambda_Stack.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FQuWwqHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d1j7zd7t38gahw.cloudfront.net/dev.to/CDK_ScheduleLambda_Stack.png" alt="ScheduleLambda Stack" width="617" height="98"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Final step&lt;/strong&gt;: Clean your resource&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; cdk destroy ScheduleLambdaStack
Are you sure you want to delete: ScheduleLambdaStack &lt;span class="o"&gt;(&lt;/span&gt;y/n&lt;span class="o"&gt;)&lt;/span&gt;? y
...
 ✅  ScheduleLambdaStack: destroyed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>tutorial</category>
      <category>cdk</category>
      <category>lambda</category>
    </item>
    <item>
      <title>Two Approaches to AWS Solution Design</title>
      <dc:creator>Vinh Le</dc:creator>
      <pubDate>Wed, 29 Jun 2022 03:59:20 +0000</pubDate>
      <link>https://dev.to/vinhle/two-approaches-to-aws-solution-design-10cl</link>
      <guid>https://dev.to/vinhle/two-approaches-to-aws-solution-design-10cl</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z33BsnnP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1400/1%2An4GlPdAzy8EogUw_D0Ft8Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z33BsnnP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1400/1%2An4GlPdAzy8EogUw_D0Ft8Q.png" alt="AWS Well-Architected Tool" width="880" height="342"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Source: &lt;a href="https://aws.amazon.com/well-architected-tool/"&gt;https://aws.amazon.com/well-architected-tool/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After several years working with AWS services in multiple projects with different roles from developer, operator to architect, when I design or evaluate a solution, I am using two approaches: &lt;em&gt;AWS in DevOps model and &lt;a href="https://aws.amazon.com/architecture/well-architected/"&gt;Well-Architected Framework&lt;/a&gt;&lt;/em&gt;. They are very useful for both real work and all AWS certified examinations (specially for AWS Solutions Architect/DevOps Professional).&lt;/p&gt;

&lt;h2&gt;
  
  
  1. AWS in DevOps model
&lt;/h2&gt;

&lt;p&gt;Development and operation processes in each organization are different, but they often contain plan, design, development, deployment and operation stages. Leveraging AWS services in our processes should be considered seriously to maximize benefits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plan stage&lt;/strong&gt;: In this stage, we often collect and evaluate requirements, then select appropriate AWS services. It requires basic knowledge and experience on many AWS services across domains from network, computation, storage, management, security to developer tools. If the target is a production environment, PaaS should be preferred over IaaS, such as &lt;a href="https://aws.amazon.com/rds/aurora/"&gt;Aurora&lt;/a&gt; over MySQL installed on EC2. However, do not limit yourself and avoid vendor lock-in, sometimes combination with other SaaS (e.g., &lt;a href="https://slack.com/"&gt;Slack&lt;/a&gt; or open source solution (e.g., &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; can create great solutions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design stage&lt;/strong&gt;: In this stage, we often configure services and decide how they communicate together. Multi-tier, &lt;a href="https://aws.amazon.com/serverless/"&gt;serverless&lt;/a&gt; and &lt;a href="https://aws.amazon.com/microservices/"&gt;micro-services&lt;/a&gt; are very common architectures which an architect should be familiar with. There are three common types of design task: new solutions, existing solutions improvement and migration. The first one, design for new solutions, we start from zero, but we may enjoy flexibility in decisions. We should determine requirements from multiple views including security &amp;amp; control, scalability &amp;amp; availability &amp;amp; reliability, and performance &amp;amp; cost. The second one, continuous improvement for existing solutions, we often troubleshoot and determine improvement strategy based on &lt;a href="https://aws.amazon.com/architecture/well-architected/"&gt;Well-Architected Framework&lt;/a&gt;. The last one, migration plan, we may start with a legacy application on-premises, and such tasks are sometime not easy due to a lot of unmaintained resources. We need to measure current workloads, select migration tools &amp;amp; services, and implement &lt;a href="https://aws.amazon.com/blogs/enterprise-strategy/6-strategies-for-migrating-applications-to-the-cloud/"&gt;6R’s strategies&lt;/a&gt; (rehosting, replatforming, refactoring / re-architecting, retire and retain)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Development stage&lt;/strong&gt;: In this stage, functional requirements and designs are translated into application code and configuration. To develop and debug cloud-based applications, we need to have knowledge at application level and follow best practices of each service to leverage the power of cloud. Besides, we will find that AWS CLI and SDK (e.g. boto3) are very useful for our work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment stage&lt;/strong&gt;: Deployment/release stage should be performed quickly and has minimum downtime and human interaction. AWS provides us a set of flexible services to realize DevOps best practices such as Infrastructure as Code (IaC), Continuous Integration (CI) and Continuous Deployment - Delivery (CD). Depending on tasks, we can use other tools (e.g. &lt;a href="https://www.jenkins.io/"&gt;Jenkins&lt;/a&gt; to support our complex scenarios. To minimize downtime, we also should to be familiar with different deployment strategies, such as rolling updates, blue-green and canary release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operation stage&lt;/strong&gt;: In this stage, we try to reduce operational complexity, optimize cost, and increase monitoring insights. Specially in a large organization, we should determine scalable operations with cross-account authentication &amp;amp; authorization &amp;amp; networking &amp;amp; monitoring &amp;amp; encryption and logging. Suppose that we have thousands resources for each business project, and hundreds projects across hundreds accounts, we may be unaware of unnecessary resources and waste a lot of money. We should define a cost-effective pricing model (e.g. on-demand, reservation, spot) based on requirements, cost reduction suggestion, budget notification and bill analysis to ensure cost optimization. Besides, in large application a monitoring system with a remediate and health recovery strategy should be designed carefully.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Well-Architected Framework
&lt;/h2&gt;

&lt;p&gt;AWS published &lt;a href="https://aws.amazon.com/architecture/well-architected/"&gt;Well-Architected Framework&lt;/a&gt;, that describes key concepts, design principles, and architectural best practices for designing and running workloads in the cloud. It is a valuable resource, specially for an AWS solution architect, in order to design architecture, evaluate workloads and identify risk issues. Design principles are summarized as below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operational Excellence Pillar&lt;/strong&gt;: the ability to support development and run workloads effectively, gain insight into their operations, and to continuously improve supporting processes and procedures to deliver business value.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are 5 design principles for operational excellence in the cloud.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perform operations as code: implement infrastructure | middleware | application configuration | operational procedures as code, and automatic executions by event triggers.&lt;/li&gt;
&lt;li&gt;Make frequent, small, reversible changes: frequently release in small (CI/CD) and reversible changes (blue-green, canary).&lt;/li&gt;
&lt;li&gt;Refine operations procedures frequently: regularly review, validate and evolve procedures appropriately as workload evaluation.&lt;/li&gt;
&lt;li&gt;Anticipate failure: simulate - test failure scenarios (e.g. Chaos Monkey), validate their impacts, and prepare responses (notification, diagnosis and auto-recovery).&lt;/li&gt;
&lt;li&gt;Learn from all operational failures: learn from all operational events and share knowledge across teams.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Security Pillar&lt;/strong&gt;: the ability to protect data, systems and assets while taking advantage of cloud technologies to improve your security.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are 7 design principles for security in the cloud.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement a strong identity foundation: implement least privilege, duty separation (authorization) and centralized authentication management; eliminate long-term static credentials.&lt;/li&gt;
&lt;li&gt;Enable traceability: monitor, alert, and audit actions and changes in real time. Integrate log and metric to automatically analyze and take actions.&lt;/li&gt;
&lt;li&gt;Apply security at all layers: deep security control from network, computing, storage, OS, code to application.&lt;/li&gt;
&lt;li&gt;Automate security best practices&lt;/li&gt;
&lt;li&gt;Protect data in transit and at rest: classify data into sensitivity levels and use mechanisms, such as encryption, tokenization, and access control.&lt;/li&gt;
&lt;li&gt;Keep people away from data: reduce or eliminate the need for direct access or manual processing of data.&lt;/li&gt;
&lt;li&gt;Prepare for security events: prepare incident management, investigation processes, and mitigation-recovery actions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Reliability Pillar&lt;/strong&gt;: the ability of a workload to perform its intended function correctly and consistently when it’s expected to. Furthermore, the ability to operate and test the workload through its total lifecycle.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are 5 design principles for reliability in the cloud.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically recover from failure: perform automatic notification, tracking of failures, and recovery processes by monitor KPIs measuring business value (not technical aspects) of services.&lt;/li&gt;
&lt;li&gt;Test recovery procedures: simulate different failures, then test and validate recovery strategies.&lt;/li&gt;
&lt;li&gt;Scale horizontally to increase aggregate workload availability: distribute requests across multiple and smaller resources to reduce the impact of a single failure.&lt;/li&gt;
&lt;li&gt;Stop guessing capacity: automatically add or remove resources to maintain the optimal level to satisfy demand without over- or under-provisioning.&lt;/li&gt;
&lt;li&gt;Manage change in automation: manage changes with version control, and apply changes by using automation mechanism.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Performance Efficiency Pillar&lt;/strong&gt;: the ability to use resources efficiently to meet system requirements, and to maintain that efficiency as demand changes and technologies evolve.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are 5 design principles for performance efficiency in the cloud.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Democratize advanced technologies: delegate complex tasks to your cloud vendor, and consider consuming the technology as a service.&lt;/li&gt;
&lt;li&gt;Go global in minutes&lt;/li&gt;
&lt;li&gt;Use serverless architectures: removes the operational burden of managing physical servers, and can lower transactional costs&lt;/li&gt;
&lt;li&gt;Experiment more often&lt;/li&gt;
&lt;li&gt;Consider mechanical sympathy: use the technology approach that aligns best with your workload goals&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Cost Optimization Pillar&lt;/strong&gt;: the ability to run systems to deliver business value at the lowest price point.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are ﬁve design principles for cost optimization in the cloud.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement cloud financial management&lt;/li&gt;
&lt;li&gt;Adopt a consumption model: pay only for the computing resources that you require and increase or decrease usage depending on business requirements, not by using elaborate forecasting&lt;/li&gt;
&lt;li&gt;Measure overall efficiency: measure the business output of the workload and the costs associated with delivering it&lt;/li&gt;
&lt;li&gt;Stop spending money on undifferentiated heavy lifting&lt;/li&gt;
&lt;li&gt;Analyze and attribute expenditure: identify the usage and cost of systems, which allows transparent attribution of IT costs to individual workload owner.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/architecture/well-architected/"&gt;AWS Well-Architected and the Five Pillars&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/certification/certified-devops-engineer-professional/"&gt;AWS Certified DevOps Engineer-Professional&lt;/a&gt; exam guide&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/certification/certified-solutions-architect-professional/"&gt;AWS Certified Solutions Architect-Professional&lt;/a&gt; exam guide&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/enterprise-strategy/6-strategies-for-migrating-applications-to-the-cloud/"&gt;AWS Blog: 6 Strategies for Migrating Applications to the Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/devops/"&gt;DevOps and AWS, Tooling and infrastructure resources for DevOps practitioners&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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