<?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: Nurul Ramadhona</title>
    <description>The latest articles on DEV Community by Nurul Ramadhona (@nurulramadhona).</description>
    <link>https://dev.to/nurulramadhona</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%2F728053%2F2b948594-d85a-4605-b7ad-4714434bdadf.png</url>
      <title>DEV Community: Nurul Ramadhona</title>
      <link>https://dev.to/nurulramadhona</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nurulramadhona"/>
    <language>en</language>
    <item>
      <title>An Easy Way to Migrate Emails to the Amazon Workmail</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Mon, 27 Mar 2023 03:40:33 +0000</pubDate>
      <link>https://dev.to/aws-builders/an-easy-way-to-migrate-emails-to-the-amazon-workmail-4oa9</link>
      <guid>https://dev.to/aws-builders/an-easy-way-to-migrate-emails-to-the-amazon-workmail-4oa9</guid>
      <description>&lt;p&gt;Have you decided to move your resources to AWS? Resources are not only about storage or anything to build your application, right? Something you use to communicate with your customers or business partners is also an important thing. Amazon Workmail is the answer for our email service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fk0v2icn0m60i85amh8fo.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk0v2icn0m60i85amh8fo.png" alt="Amazon Workmail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've created some posts in this series but those are for something built from scratch. Then, I thought what if we want to migrate our emails from the current hosting provider to AWS? So in this section, I'll show you the easy way that AWS already provided &lt;strong&gt;at no cost&lt;/strong&gt;. Actually, there are &lt;a href="https://aws.amazon.com/workmail/features/" rel="noopener noreferrer"&gt;two migration specialists&lt;/a&gt; we can use but here I choose one of them which doesn't require us to install anything. It's web-based so we can easily access it anywhere. We will use &lt;a href="https://workmail.audriga.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;audriga&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F7qjkznxnngcthblnkwzj.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qjkznxnngcthblnkwzj.png" alt="audriga"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we migrate, we need to do a few things "carefully" because the state of our domain or the email itself is &lt;strong&gt;in use&lt;/strong&gt;. So, these are the steps I created to do before we migrate all emails.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Announce your migration schedule a few days before you do that to all email users and tell them the next steps they should take after the migration process has been done, such as changing the default password, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start to create the Amazon Workmail resources, consisting of an organization, some users along with the emails as the target and an administrator (I'll tell you what it's used for later).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I suggest you do the migration at a time when the users are not actively using their emails like at midnight for example as we usually do for maintenance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set the required DNS records provided by AWS &lt;strong&gt;&lt;em&gt;except&lt;/em&gt;&lt;/strong&gt; the MX record. But if there is no more email transaction at that time, you can go ahead with all records.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start migrating the emails.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since I don't have email hosted somewhere, I'll do two types of migration. First is manual migration from Outlook to Workmail. Then, the second one is batch migration between two Workmail organizations (here we will also see how to migrate either &lt;strong&gt;from&lt;/strong&gt; or &lt;strong&gt;to&lt;/strong&gt; Workmail).&lt;/p&gt;

&lt;p&gt;Now we are ready to go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Create The Amazon Workmail Resources
&lt;/h2&gt;

&lt;p&gt;In this step, we just need to create an organization along with registering the external domain. Here I use the domain &lt;code&gt;dhona.xyz&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws workmail create-organization --alias dhona --domains DomainName=dhona.xyz --region us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;*: it's not mandatory to use an external domain since AWS gives us a domain alias for each organization &lt;code&gt;subdomain.awsapps.com&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set The Required DNS Records
&lt;/h2&gt;

&lt;p&gt;Please set the DNS records generated by Workmail and make sure all are verified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws workmail get-mail-domain --domain-name dhona.xyz --organization-id m-44968df215c443dea726cd731821614a --region us-east-1
DkimVerificationStatus: PENDING
IsDefault: false
IsTestDomain: false
OwnershipVerificationStatus: PENDING
Records:
(the record will be shown here)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we set the DNS properly, it should be successfully verified.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fcerpje9fhza0d3p32ptk.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcerpje9fhza0d3p32ptk.png" alt="Domain Verification"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start The Migration Process
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Manual Migration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This method we can use to migrate a single email or only for a few users (small quantities). So in the beginning, we will create one email user as the target of Outlook's email.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws workmail create-user --organization-id m-44968df215c443dea726cd731821614a --name dhonaxyz --display-name "Nurul Ramadhona" --password $password --region us-east-1
$ aws workmail register-to-work-mail --organization-id m-44968df215c443dea726cd731821614a --entity-id bdb219b2-c7ed-4c0e-8e04-293b5bd69127 --email dhonaxyz@dhona.xyz --region us-east-1
$ aws workmail describe-user --user-id bdb219b2-c7ed-4c0e-8e04-293b5bd69127 --organization-id m-44968df215c443dea726cd731821614a --region us-east-1
DisplayName: Nurul Ramadhona
Email: dhonaxyz@dhona.xyz
EnabledDate: '2023-03-26T12:52:35.822000+07:00'
Name: dhonaxyz
State: ENABLED
UserId: bdb219b2-c7ed-4c0e-8e04-293b5bd69127
UserRole: USER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I mentioned above, we will use audriga. Here are the steps on how to use it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the link =&amp;gt; &lt;a href="https://app.workmail.audriga.com/?client=workmail" rel="noopener noreferrer"&gt;https://app.workmail.audriga.com/?client=workmail&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6flhg15cvb2aaiwnrju1.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6flhg15cvb2aaiwnrju1.png" alt="audriga 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select the provider (source and target).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2F1hxt2bvw15m60p0skzmc.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hxt2bvw15m60p0skzmc.png" alt="audriga 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter the email account details (source and target). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because we migrate in user mode, we should enter the email and password manually. Make sure both passed the validation checks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvpudzhp15xa73mz5sttt.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpudzhp15xa73mz5sttt.png" alt="audriga 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start the migration (we can leave the screen because we will get an email notification once the migration has been configured, started and completed).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fx0kw5izj86ypfzmubhmu.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0kw5izj86ypfzmubhmu.png" alt="audriga 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fl0yx3afr5wv3z5qpdlh7.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0yx3afr5wv3z5qpdlh7.png" alt="audriga 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check if the emails exist on the target email (the source email currently has two emails, each one email on Inbox and Sent Items).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkg4zyqolsw98igq800e6.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkg4zyqolsw98igq800e6.jpg" alt="outlook workmail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fyp5qnr75fb3whkm5uvfg.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyp5qnr75fb3whkm5uvfg.png" alt="outlook inbox"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fircm9178kxlt3m5buaz5.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fircm9178kxlt3m5buaz5.png" alt="outlook sent"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Batch migration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We have successfully migrated a single account. That's good, right? But what if we have a large number of users? Should we migrate all one by one?&lt;/p&gt;

&lt;p&gt;Don't worry! We can use a template file (usually in .csv) for uploading the users' details. This is a common thing for managing email services.&lt;/p&gt;

&lt;p&gt;Since we will do batch migration. Please create some target users along with the emails on the Workmail. Make sure all users are created and enabled. You can use the following Ansible playbook I created:&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="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="s"&gt;workmail-users&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
  &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
  &lt;span class="na"&gt;gather_facts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;no&lt;/span&gt;

  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&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="s"&gt;create users&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws workmail create-user --organization-id your-org-id --name "{{ item.username }}" --display-name "{{ item.fullname }}" --password "{{ item.pass }}" --region your-choosen-region&lt;/span&gt;
      &lt;span class="na"&gt;loop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user1"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pass&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passwordup2U!"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;fullname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user2"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pass&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passwordup2U!"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;fullname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;2"&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user3"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pass&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passwordup2U!"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;fullname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user4"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pass&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passwordup2U!"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;fullname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;4"&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user5"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pass&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passwordup2U!"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;fullname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;5"&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="nv"&gt;create&lt;/span&gt;&lt;span class="pi"&gt;]&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="s"&gt;list users&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;workmail&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;list-users&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--organization-id&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;your-org-id&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--region&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;your-choosen-region&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--query&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'Users[?Name==`{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;item.username&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}`].Id'&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;id-list.txt"&lt;/span&gt;
      &lt;span class="na"&gt;loop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user1"&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user2"&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user3"&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user4"&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user5"&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="nv"&gt;list&lt;/span&gt;&lt;span class="pi"&gt;]&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="s"&gt;list users id&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cat&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;id-list.txt'&lt;/span&gt;
      &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;list_id&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="nv"&gt;list&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;var&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;list_id.stdout_lines&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="nv"&gt;list&lt;/span&gt;&lt;span class="pi"&gt;]&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="s"&gt;enable users&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws workmail register-to-work-mail --organization-id your-org-id --entity-id "{{ item.userid }}" --email "{{ item.email }}" --region your-choosen-region&lt;/span&gt;
      &lt;span class="na"&gt;loop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;userid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user1id"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user1@your.domain"&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;userid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user2id"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user2@your.domain"&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;userid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user3id"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user3@your.domain"&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;userid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user4id"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user4@your.domain"&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;userid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user5id"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user5@your.domain"&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="nv"&gt;enable&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;*: Please enter the value with your own user's details as well as the number of users. Then, run the 'enable' tag separately as we need the &lt;code&gt;entity-id&lt;/code&gt; values after the 'create' and 'list' tags.&lt;/p&gt;

&lt;p&gt;Here I create 5 users as example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F7e58tn6944oa14r1nm02.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7e58tn6944oa14r1nm02.png" alt="workmail target users"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also need to enable migration permission and choose an administrator. By using administrator, we can migrate all emails without providing each user's password. Yes, we only use the credential of the administrator as it has access to all users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F580xt41gahdbktoh67oa.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F580xt41gahdbktoh67oa.png" alt="workmail migration administrator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, because I migrate between two Workmail organizations. I'll create one more organization as I do for the target organization. I'll migrate from &lt;code&gt;nurul.awsapps.com&lt;/code&gt; to &lt;code&gt;dhona.xyz&lt;/code&gt; which both are hosted on Workmail. But if you currently have emails hosted somewhere, you don't need to do this.&lt;/p&gt;

&lt;p&gt;Now, we are ready to migrate the emails! The steps are similar to the manual migration above, so here I'll mention the difference between them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select the provider (source and target). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because I'll do migration between two Workmail organizations, I choose the same source and target provider. In case the source (your current email service) is hosted somewhere, please choose to add the missing provider or server and enter the details needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6cst3pkyew0y58p9d5p0.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6cst3pkyew0y58p9d5p0.png" alt="audriga 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fo2h6nn0souqomom8sddq.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2h6nn0souqomom8sddq.png" alt="audriga 7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure the account by choosing to add multiple accounts, then upload the &lt;code&gt;.csv&lt;/code&gt; file. Here's the example:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Frwybs4c26cokuobxu3pg.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwybs4c26cokuobxu3pg.png" alt="audriga 8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkwckfef9c8ioufx29rrp.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwckfef9c8ioufx29rrp.png" alt="audriga 9"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fdrwc0i23j2rcwc2cpkun.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrwc0i23j2rcwc2cpkun.png" alt="audriga 10"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkdgrfcwbu61f7sv6odss.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdgrfcwbu61f7sv6odss.png" alt="audriga 11"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start the migration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fwpe6raai0gnb6po37h9z.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpe6raai0gnb6po37h9z.png" alt="audriga 12"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fa9zwxhawy8kbpq5jl71r.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9zwxhawy8kbpq5jl71r.png" alt="audriga 13"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the email. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here before I did migration, I sent a test email to all source emails. As we can see above there are 5 accounts that have been migrated and each contains 1 email. Then, I'll log in to one of those five users to see if the email exists.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fli3tyz5tbgfo7adfvz42.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fli3tyz5tbgfo7adfvz42.png" alt="audriga 14"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvmvmq5x1zd3j8wenterg.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmvmq5x1zd3j8wenterg.png" alt="audriga 15"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it! It's very easy, right? AWS has provide us the easy way and the &lt;strong&gt;self-service&lt;/strong&gt; as well, so we can do it independently anytime we need to migrate to Amazon Workmail.&lt;/p&gt;

&lt;p&gt;Alright! Last but not least, don't forget to follow me for more content! Thank you!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>workmail</category>
      <category>hosting</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Clean Up AWS Resources - Amazon Workmail</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Sat, 25 Mar 2023 14:23:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/clean-up-aws-resources-amazon-workmail-1can</link>
      <guid>https://dev.to/aws-builders/clean-up-aws-resources-amazon-workmail-1can</guid>
      <description>&lt;p&gt;So far, we have done many things to explore how Amazon Workmail works so we can host our email services there. In this section, I'll show you how to delete any resources we created within Amazon Workmail through AWS CLI. Please don't misunderstand! I'm not here to ask you to stop using AWS services but I'm here to show you how to delete it in case you may want to create a new resource or replace an existing one.&lt;/p&gt;

&lt;p&gt;If you have followed me on the second post of this series, here's the cleanup process. It has its own flow to delete the resources, so please follow the following instructions without missing a single step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deregister User &amp;amp; Group From Workmail
&lt;/h2&gt;

&lt;p&gt;It will disassociate a user/group, mark it as no longer used and change the state to disabled. Here we will create a simple bash script for the repetitive tasks.&lt;/p&gt;

&lt;p&gt;Before that, let's gather all the information needed (ID of user/group to be deleted)!&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;aws workmail list-groups &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 | &lt;span class="nb"&gt;grep &lt;/span&gt;Id
  Id: bcefb7d0-1f5a-45e4-8ef4-853a74823e86
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail list-users &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 | &lt;span class="nb"&gt;grep &lt;/span&gt;Id
  Id: 3815a14e-e0d1-4d31-b998-bb290589191c
  Id: 4b1d1dd0-4c9a-451a-83de-4145063999f0
  Id: 510f7b96-800d-47e2-a869-c3c47af4e9ea
  Id: a036c622-4d14-4075-b2a4-9a17975cbc83
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we will copy-paste the ID:&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;cat &lt;/span&gt;delete-emails.sh 
&lt;span class="c"&gt;#! /bin/sh&lt;/span&gt;
aws workmail deregister-from-work-mail &lt;span class="nt"&gt;--entity-id&lt;/span&gt; bcefb7d0-1f5a-45e4-8ef4-853a74823e86 &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 
aws workmail deregister-from-work-mail &lt;span class="nt"&gt;--entity-id&lt;/span&gt; 3815a14e-e0d1-4d31-b998-bb290589191c &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
aws workmail deregister-from-work-mail &lt;span class="nt"&gt;--entity-id&lt;/span&gt; 4b1d1dd0-4c9a-451a-83de-4145063999f0 &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
aws workmail deregister-from-work-mail &lt;span class="nt"&gt;--entity-id&lt;/span&gt; 510f7b96-800d-47e2-a869-c3c47af4e9ea &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
aws workmail deregister-from-work-mail &lt;span class="nt"&gt;--entity-id&lt;/span&gt; a036c622-4d14-4075-b2a4-9a17975cbc83 &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x delete-emails.sh 
&lt;span class="nv"&gt;$ &lt;/span&gt;./delete-emails.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now all users and groups are disabled and ready to be deleted:&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;aws workmail list-groups &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 | &lt;span class="nb"&gt;grep &lt;/span&gt;State
  State: DISABLED
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail list-users &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 | &lt;span class="nb"&gt;grep &lt;/span&gt;State
  State: DISABLED
  State: DISABLED
  State: DISABLED
  State: DISABLED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Delete User &amp;amp; Group
&lt;/h2&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;delete-usergroup.sh 
&lt;span class="c"&gt;#! /bin/sh&lt;/span&gt;
aws workmail delete-group &lt;span class="nt"&gt;--group-id&lt;/span&gt; bcefb7d0-1f5a-45e4-8ef4-853a74823e86 &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
aws workmail delete-user &lt;span class="nt"&gt;--user-id&lt;/span&gt; 3815a14e-e0d1-4d31-b998-bb290589191c &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
aws workmail delete-user &lt;span class="nt"&gt;--user-id&lt;/span&gt; 4b1d1dd0-4c9a-451a-83de-4145063999f0 &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
aws workmail delete-user &lt;span class="nt"&gt;--user-id&lt;/span&gt; 510f7b96-800d-47e2-a869-c3c47af4e9ea &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
aws workmail delete-user &lt;span class="nt"&gt;--user-id&lt;/span&gt; a036c622-4d14-4075-b2a4-9a17975cbc83 &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x delete-usergroup.sh 
&lt;span class="nv"&gt;$ &lt;/span&gt;./delete-usergroup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the state one more time!&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;aws workmail list-groups &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
Groups:
- DisabledDate: &lt;span class="s1"&gt;'2023-03-23T21:06:45.687000+07:00'&lt;/span&gt;
  EnabledDate: &lt;span class="s1"&gt;'2023-03-23T20:40:45.076000+07:00'&lt;/span&gt;
  Id: bcefb7d0-1f5a-45e4-8ef4-853a74823e86
  Name: developers
  State: DELETED
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail list-users &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 | &lt;span class="nb"&gt;grep &lt;/span&gt;State
  State: DELETED
  State: DELETED
  State: DELETED
  State: DELETED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deregister External Domain
&lt;/h2&gt;

&lt;p&gt;If we use an external domain as the default one, please change it first at least to the domain alias provided by Workmail.&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;aws workmail update-default-mail-domain &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--domain-name&lt;/span&gt; dhona.awsapps.com &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail deregister-mail-domain &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--domain-name&lt;/span&gt; dhona.xyz &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Delete The Organization
&lt;/h2&gt;

&lt;p&gt;This is the last step and make sure you have deleted all things above. If you find an error, please repeat those tasks because you may skip some steps.&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;aws workmail delete-organization &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--delete-directory&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
OrganizationId: m-fb75a642ab0f4745b33b54f729f6af01
State: Deleting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright! That's it for now! I think we can do more things with Amazon Workmail so I won't say that this is the last part of this series. Please look forward to it and don't forget to follow this blog! Thank you!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>workmail</category>
      <category>hosting</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to Build Reputation of Email Hosted on Amazon Workmail</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Sat, 25 Mar 2023 14:22:41 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-build-reputation-of-email-hosted-on-amazon-workmail-1lop</link>
      <guid>https://dev.to/aws-builders/how-to-build-reputation-of-email-hosted-on-amazon-workmail-1lop</guid>
      <description>&lt;p&gt;In the previous post, we already and successfully hosted our emails on Amazon Workmail. We also tested sending/receiving email within the same domain and it works well, no problem so far. Now, let's see how is it going outside! Because a company doesn't only communicate between departments (internal) but also with external like business partners for example. Then, because this is just a practice and I don't have a company to work with (other domains). So I'll show you how our email goes to famous email providers, I mean it's like commonly everyone has an account at least on one of those providers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;By the way, I'm sorry if you will see lots of images on this post since nothing to do with the configurations through AWS CLI :)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To check how it works, we will send emails to Google Mail, Yahoo and Microsoft from two different domains. One from Workmail alias &lt;code&gt;dhona.awsapps.com&lt;/code&gt; and one external domain &lt;code&gt;dhona.xyz&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. GMAIL
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First Email Results&lt;/strong&gt;: Email from &lt;code&gt;dhona.awsapps.com&lt;/code&gt; is delivered to Inbox and email from &lt;code&gt;dhona.xyz&lt;/code&gt; is marked as SPAM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pcUwNAVT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/psxr3cjssfhwxrkbzva4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pcUwNAVT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/psxr3cjssfhwxrkbzva4.png" alt="Workmail GMAIL 1" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3LOPcYN4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cklphm5891r6zial45hz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3LOPcYN4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cklphm5891r6zial45hz.png" alt="Workmail GMAIL 2" width="519" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O66yp-1f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7l6lxg58ghsa3ipgea3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O66yp-1f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7l6lxg58ghsa3ipgea3b.png" alt="Workmail GMAIL 3" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--My37hDv1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8yovdvnufyqu2zgw3ma3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--My37hDv1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8yovdvnufyqu2zgw3ma3.png" alt="Workmail GMAIL 4" width="433" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Second Email Results&lt;/strong&gt;: Both are delivered to Inbox.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZXAm3yix--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ntqbjum4u8l7ss1671f5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZXAm3yix--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ntqbjum4u8l7ss1671f5.png" alt="Workmail GMAIL 5" width="800" height="167"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. YAHOO
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First Email Results&lt;/strong&gt;: Both are delivered to Inbox.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PEdMbtTh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0pqdmhmbo1fym5f71ldo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PEdMbtTh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0pqdmhmbo1fym5f71ldo.png" alt="Workmail YAHOO 1" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l-Ftlg2x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/afpt8ln6yy6t4fwpu51i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l-Ftlg2x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/afpt8ln6yy6t4fwpu51i.png" alt="Workmail YAHOO 2" width="676" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Second Email Results&lt;/strong&gt;: Both are delivered to Inbox as the first email.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. OUTLOOK
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First Email Results&lt;/strong&gt;: Both are delivered to Junk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qKynIkQy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dwm2yyk4ek7f5t6ee05q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qKynIkQy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dwm2yyk4ek7f5t6ee05q.png" alt="Workmail OUTLOOK 1" width="615" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E8OxnnGX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oqu79hvlnbmxat2so29l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E8OxnnGX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oqu79hvlnbmxat2so29l.png" alt="Workmail OUTLOOK 2" width="618" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Second Email Results&lt;/strong&gt;: Both are still delivered to Junk as the first email.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;As we can see above any emails are not delivered to Inbox on the first try, even the second one as well. Don't worry! It usually happens to a new email domain although all authentications (SPF, DKIM, DMARC) checks are passed. To prevent being domain with a "bad" reputation, we can do the following actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ask the receiver to "Mark as not SPAM" for your email that went to JUNK.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep your privacy as secure as you can, it means &lt;strong&gt;not&lt;/strong&gt; using a weak password, clicking an unknown link, and many more to prevent being used to send spam, phishing, or other kinds of issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you are sure with all securities and since the emails passed the authentication checks. Ask your partners to whitelist your emails or domain or even the IP address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't send bulk emails at one time!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After we do all the above, let's check our email one more time!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lF15X7l_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w68n3vh7wm39j9ono3hq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lF15X7l_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w68n3vh7wm39j9ono3hq.png" alt="Workmail GMAIL" width="800" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---aty87E5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t05qv22anql1qkt10bo4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---aty87E5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t05qv22anql1qkt10bo4.png" alt="Workmail YAHOO" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Eujhk7Vd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eqpwccehjbz5c1ujpjx2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Eujhk7Vd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eqpwccehjbz5c1ujpjx2.png" alt="Workmail OUTLOOK" width="613" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Third emails are all successfully delivered to Inbox.&lt;/p&gt;




&lt;h2&gt;
  
  
  Additional Thing
&lt;/h2&gt;

&lt;p&gt;To check how our domain reputation is, we can use some online tools. I'll show you one of them which is MXToolbox. It helps us to know if our domain is listed somewhere.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CdFUY1er--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fan0pbmrlc6tiszgcu5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CdFUY1er--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fan0pbmrlc6tiszgcu5z.png" alt="MXTOOLBOX AWSAPPS.COM" width="638" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KNi0TcwO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4ue43zpsay9mmtd9fzu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KNi0TcwO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4ue43zpsay9mmtd9fzu.png" alt="MXTOOLBOX DHONA.XYZ" width="550" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are some DNS Blocklists that can be a reason for your email to be marked as Spam or even failed to deliver based on our domain or even IP address reputation. The ones that have the big impacts are SORBS and Barracuda. So make sure your domain is not listed anywhere for smooth email transactions. If already listed, try to delist or request removal and start to build a good reputation!&lt;/p&gt;

&lt;p&gt;By the way, feel free to comment if you have different perspectives or other things to do regarding this topic. I'll appreciate that, so we can learn together.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>workmail</category>
      <category>hosting</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Host Your Own Business Email Using Amazon Workmail</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Sat, 25 Mar 2023 14:22:26 +0000</pubDate>
      <link>https://dev.to/aws-builders/host-your-own-business-email-using-amazon-workmail-2nnp</link>
      <guid>https://dev.to/aws-builders/host-your-own-business-email-using-amazon-workmail-2nnp</guid>
      <description>&lt;p&gt;Continuing the previous post where I told you how important email is and why we choose Workmail as our email service. Then, here we will get started on how to set up email hosting using Amazon Workmail. I'll do all the steps using AWS CLI, so make sure you have installed &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;it&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html" rel="noopener noreferrer"&gt;set the credential&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Are you comfortable with the Console? Please go ahead with it, no pressure at all :)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I created this series, Amazon Workmail was only available in 3 regions. In this case, I randomly choose N. Virginia (us-east-1) and you can choose which one you wanna use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkodi4myalzsczsvw5ihy.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkodi4myalzsczsvw5ihy.png" alt="Workmail Region"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More about Amazon Workmail, click &lt;a href="https://aws.amazon.com/workmail/" rel="noopener noreferrer"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what are we gonna do?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create Organization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create User&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Register Domain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Default Domain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create User Alias&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send &amp;amp; Receive Email&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Mailbox Quota&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Associate User To The Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup Email On Mobile Email Client App&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I think those 10 steps are enough for us to get started with Amazon Workmail!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create Organization
&lt;/h2&gt;

&lt;p&gt;Here we will start using the free domain provided which is &lt;code&gt;awsapps.com&lt;/code&gt;. So please decide on the alias first, then AWS will do the rest to set up your email hosting such as domain verification along with the webmail client link provided.&lt;/p&gt;

&lt;p&gt;For example, I use &lt;code&gt;dhona&lt;/code&gt; as an alias, so AWS will verify &lt;code&gt;dhona.awsapps.com&lt;/code&gt; and use &lt;code&gt;dhona.awsapps.com/mail&lt;/code&gt; to access the webmail 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="nv"&gt;$ &lt;/span&gt;aws workmail create-organization &lt;span class="nt"&gt;--alias&lt;/span&gt; dhona &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
OrganizationId: m-fb75a642ab0f4745b33b54f729f6af01
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail describe-organization &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
ARN: arn:aws:workmail:us-east-1:0123456789:organization/m-fb75a642ab0f4745b33b54f729f6af01
Alias: dhona
CompletedDate: &lt;span class="s1"&gt;'2023-03-23T18:20:03.872000+07:00'&lt;/span&gt;
DefaultMailDomain: dhona.awsapps.com
DirectoryId: d-9067aebc88
DirectoryType: IdentityPoolDirectory
OrganizationId: m-fb75a642ab0f4745b33b54f729f6af01
State: Active
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;*: please save the &lt;code&gt;organization-id&lt;/code&gt; as we always use it for the next configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create Users
&lt;/h2&gt;

&lt;p&gt;When we're creating a user, we don't need to choose the domain that will be used directly. So it will be just a user, not an email user but the state is still disabled.&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;aws workmail create-user &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--name&lt;/span&gt; dhona &lt;span class="nt"&gt;--display-name&lt;/span&gt; &lt;span class="s2"&gt;"Nurul Ramadhona"&lt;/span&gt; &lt;span class="nt"&gt;--password&lt;/span&gt; &lt;span class="nv"&gt;$password&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
UserId: 510f7b96-800d-47e2-a869-c3c47af4e9ea
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail describe-user &lt;span class="nt"&gt;--user-id&lt;/span&gt; 510f7b96-800d-47e2-a869-c3c47af4e9ea &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
DisplayName: Nurul Ramadhona
Name: dhona
State: DISABLED
UserId: 510f7b96-800d-47e2-a869-c3c47af4e9ea
UserRole: USER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To enable the user, we will need to choose a "temporary" primary email address. Why is it temporary? Because we can change it anytime we want (I'll tell you more about it in the fifth step). By doing this, you will create an email address for that user.&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;aws workmail register-to-work-mail &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--entity-id&lt;/span&gt; 510f7b96-800d-47e2-a869-c3c47af4e9ea &lt;span class="nt"&gt;--email&lt;/span&gt; dhona@dhona.awsapps.com &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail describe-user &lt;span class="nt"&gt;--user-id&lt;/span&gt; 510f7b96-800d-47e2-a869-c3c47af4e9ea &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
DisplayName: Nurul Ramadhona
Email: dhona@dhona.awsapps.com
EnabledDate: &lt;span class="s1"&gt;'2023-03-23T19:00:40.432000+07:00'&lt;/span&gt;
Name: dhona
State: ENABLED
UserId: 510f7b96-800d-47e2-a869-c3c47af4e9ea
UserRole: USER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;*: &lt;code&gt;entity-id&lt;/code&gt; is an ID of either a user or group. Please adjust it based on your condition, you're managing a user or group. Don't get confused!&lt;/p&gt;

&lt;p&gt;Right after the user is enabled, we can log in to the webmail client and start sending/receiving emails.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fb0lh8igls54jqj6rt36x.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0lh8igls54jqj6rt36x.png" alt="Workmail Login"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fi0j5p6sjp89xg1ji36tb.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0j5p6sjp89xg1ji36tb.png" alt="Workmail Webmail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Register Domain To The Organization
&lt;/h2&gt;

&lt;p&gt;Within an organization, we can have more than one domain to be used. Since we got a free alias &lt;code&gt;dhona.awsapps.com&lt;/code&gt;, here I'll add my external domain &lt;code&gt;dhona.xyz&lt;/code&gt; (you can skip this step if you don't have one and jump to the sixth step). We can use the domain either from Amazon Route53 or external domain.&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;aws workmail register-mail-domain &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--domain-name&lt;/span&gt; dhona.xyz &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we use a custom domain, we should add some required DNS records generated by Workmail. Each record has its own purpose.&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;aws workmail get-mail-domain &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--domain-name&lt;/span&gt; dhona.xyz &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
DkimVerificationStatus: PENDING
IsDefault: &lt;span class="nb"&gt;false
&lt;/span&gt;IsTestDomain: &lt;span class="nb"&gt;false
&lt;/span&gt;OwnershipVerificationStatus: PENDING
Records:
&lt;span class="o"&gt;(&lt;/span&gt;the required DNS records will be shown here&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mail Exchange (MX)&lt;/strong&gt;: used to direct where the mail server of that domain is placed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example: &lt;code&gt;Value: 10 inbound-smtp.us-east-1.amazonaws.com.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It shows the mail server address by using the domain along with the priority which is 10. The domain can consist of more than one IP address in case we have multiple servers. Anyway, if the domain is &lt;strong&gt;in use&lt;/strong&gt; somewhere (you already hosted your email service using that domain), I suggest you wait till the migration process is done.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sender Policy Framework (SPF)&lt;/strong&gt;: used to list all addresses that are allowed to send email using the domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example: &lt;code&gt;Value: v=spf1 include:amazonses.com ~all&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It means all emails that don't come from &lt;code&gt;amazonses.com&lt;/code&gt; should be marked as insecure or spam.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DomainKeys Identified Mail (DKIM)&lt;/strong&gt;: used by the receiver to verify emails using the key signed through cryptographic authentication. The hostname is marked with &lt;code&gt;._domainkey&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example: &lt;code&gt;Value: abcdefghijklmnopqrstuvwxyz.dkim.amazonses.com.&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain-based Message Authentication, Reporting and Conformance (DMARC)&lt;/strong&gt;: used to decide the action if the authentication is failed. This is just an additional record after SPF and DKIM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example: &lt;code&gt;Value: v=DMARC1;p=quarantine;pct=100;fo=1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It means the receiver should quarantine all emails that don't pass the authentication checks and generate a report to the sender when the emails fail to deliver.&lt;/p&gt;

&lt;p&gt;Those 3 things are parts of email security. You can get to know more about them and you can also make them custom as you need. In this case, I'll follow what Workmail has generated for me. If we already set the DNS records properly, the domain will be successfully verified and ready to be used.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Update Default Domain
&lt;/h2&gt;

&lt;p&gt;Since now we have two domains, we are free to choose which one will be used as the default domain.&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;aws workmail update-default-mail-domain &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--domain-name&lt;/span&gt; dhona.xyz &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail describe-organization &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
ARN: arn:aws:workmail:us-east-1:0123456789:organization/m-fb75a642ab0f4745b33b54f729f6af01
Alias: dhona
CompletedDate: &lt;span class="s1"&gt;'2023-03-23T18:20:03.872000+07:00'&lt;/span&gt;
DefaultMailDomain: dhona.xyz
DirectoryId: d-9067aebc88
DirectoryType: IdentityPoolDirectory
OrganizationId: m-fb75a642ab0f4745b33b54f729f6af01
State: Active
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail list-mail-domains &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
MailDomains:
- DefaultDomain: &lt;span class="nb"&gt;false
  &lt;/span&gt;DomainName: dhona.awsapps.com
- DefaultDomain: &lt;span class="nb"&gt;true
  &lt;/span&gt;DomainName: dhona.xyz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Create User Alias
&lt;/h2&gt;

&lt;p&gt;Alias in this section is different from alias of the organization. When we create a user, the user can have multiple email addresses using different domains registered on Workmail. One acts as the primary email address and the rest as aliases. It's a good choice if you have more than one domain but you want to use the same username. All emails sent to an alias will be directed to and received by the primary email address.&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;aws workmail create-alias &lt;span class="nt"&gt;--entity-id&lt;/span&gt; 510f7b96-800d-47e2-a869-c3c47af4e9ea &lt;span class="nt"&gt;--alias&lt;/span&gt; dhona@dhona.xyz &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I said above, we can change our primary email address anytime we want. So I'll make &lt;code&gt;dhona@dhona.xyz&lt;/code&gt; as primary email of the user named &lt;code&gt;dhona&lt;/code&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;aws workmail update-primary-email-address &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--entity-id&lt;/span&gt; 510f7b96-800d-47e2-a869-c3c47af4e9ea &lt;span class="nt"&gt;--email&lt;/span&gt; dhona@dhona.xyz &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail list-users &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
Users:
- DisplayName: Nurul Ramadhona
  Email: dhona@dhona.xyz
  EnabledDate: &lt;span class="s1"&gt;'2023-03-23T19:00:40.432000+07:00'&lt;/span&gt;
  Id: 510f7b96-800d-47e2-a869-c3c47af4e9ea
  Name: dhona
  State: ENABLED
  UserRole: USER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Send &amp;amp; Receive Email
&lt;/h2&gt;

&lt;p&gt;For testing the email, we will create one more user and we will see if it works along with SPF, DKIM and DMARC checks.&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;aws workmail create-user &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--name&lt;/span&gt; nurul &lt;span class="nt"&gt;--display-name&lt;/span&gt; &lt;span class="s2"&gt;"Nurul Ramadhona"&lt;/span&gt; &lt;span class="nt"&gt;--password&lt;/span&gt; &lt;span class="nv"&gt;$password&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
UserId: 4b1d1dd0-4c9a-451a-83de-4145063999f0
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail register-to-work-mail &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--entity-id&lt;/span&gt; 4b1d1dd0-4c9a-451a-83de-4145063999f0 &lt;span class="nt"&gt;--email&lt;/span&gt; nurul@dhona.xyz &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail describe-user &lt;span class="nt"&gt;--user-id&lt;/span&gt; 4b1d1dd0-4c9a-451a-83de-4145063999f0 &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
DisplayName: Nurul Ramadhona
Email: nurul@dhona.xyz
EnabledDate: &lt;span class="s1"&gt;'2023-03-23T20:03:58.821000+07:00'&lt;/span&gt;
Name: nurul
State: ENABLED
UserId: 4b1d1dd0-4c9a-451a-83de-4145063999f0
UserRole: USER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F2cq856mhjn580w1ahqfo.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cq856mhjn580w1ahqfo.png" alt="Workmail SPF DKIM DMARC"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a test email within the same domain, passed all authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Update Mailbox Quota
&lt;/h2&gt;

&lt;p&gt;With Workmail, we are free to customize the quota of each mailbox. By default, each user gets 50GB and we are allowed to increase or decrease as we need.&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;aws workmail get-mailbox-details &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--user-id&lt;/span&gt; 4b1d1dd0-4c9a-451a-83de-4145063999f0 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
MailboxQuota: 51200
MailboxSize: 0.010987281799316406
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail update-mailbox-quota &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--user-id&lt;/span&gt; 4b1d1dd0-4c9a-451a-83de-4145063999f0 &lt;span class="nt"&gt;--mailbox-quota&lt;/span&gt; 12800 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail get-mailbox-details &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--user-id&lt;/span&gt; 4b1d1dd0-4c9a-451a-83de-4145063999f0 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
MailboxQuota: 12800
MailboxSize: 0.02144145965576172
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Create Group
&lt;/h2&gt;

&lt;p&gt;A group always be the best practice for managing users. Let's say we have a company that consists of many departments such as HR, Marketing, Developers, etc. It will be easier to spread information to all members of each department so no one will lose any updates.&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;aws workmail create-group &lt;span class="nt"&gt;--name&lt;/span&gt; developers &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
GroupId: bcefb7d0-1f5a-45e4-8ef4-853a74823e86
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail register-to-work-mail &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--entity-id&lt;/span&gt; bcefb7d0-1f5a-45e4-8ef4-853a74823e86 &lt;span class="nt"&gt;--email&lt;/span&gt; developers@dhona.xyz &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail list-groups &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
Groups:
- Email: developers@dhona.xyz
  EnabledDate: &lt;span class="s1"&gt;'2023-03-23T20:40:45.076000+07:00'&lt;/span&gt;
  Id: bcefb7d0-1f5a-45e4-8ef4-853a74823e86
  Name: developers
  State: ENABLED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. Associate User To The Group
&lt;/h2&gt;

&lt;p&gt;Now, we will add some users to the Developers group and use &lt;code&gt;developers@dhona.xyz&lt;/code&gt; as the email address (should not already used by other groups/users).&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;aws workmail associate-member-to-group &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--group-id&lt;/span&gt; bcefb7d0-1f5a-45e4-8ef4-853a74823e86 &lt;span class="nt"&gt;--member-id&lt;/span&gt; 3815a14e-e0d1-4d31-b998-bb290589191c &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail associate-member-to-group &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--group-id&lt;/span&gt; bcefb7d0-1f5a-45e4-8ef4-853a74823e86 &lt;span class="nt"&gt;--member-id&lt;/span&gt; 510f7b96-800d-47e2-a869-c3c47af4e9ea &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws workmail list-group-members &lt;span class="nt"&gt;--organization-id&lt;/span&gt; m-fb75a642ab0f4745b33b54f729f6af01 &lt;span class="nt"&gt;--group-id&lt;/span&gt; bcefb7d0-1f5a-45e4-8ef4-853a74823e86 &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
Members:
- EnabledDate: &lt;span class="s1"&gt;'2023-03-23T18:37:51.155000+07:00'&lt;/span&gt;
  Id: 3815a14e-e0d1-4d31-b998-bb290589191c
  Name: admin
  State: ENABLED
  Type: USER
- EnabledDate: &lt;span class="s1"&gt;'2023-03-23T19:00:40.432000+07:00'&lt;/span&gt;
  Id: 510f7b96-800d-47e2-a869-c3c47af4e9ea
  Name: dhona
  State: ENABLED
  Type: USER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll log in to one of the members.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvisqywkivs8ugj3wwpq6.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvisqywkivs8ugj3wwpq6.png" alt="Workmail Send Email To Group"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fiarvbyyp6s33nhn6li7c.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiarvbyyp6s33nhn6li7c.png" alt="Workmail Receive Email From Group"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Setup Email On Mobile Email Client App
&lt;/h2&gt;

&lt;p&gt;The webmail client provided by Workmail is not the only email client we can use. As with other email services, we can set up our email on mobile too by using the Microsoft Exchange option. Here is how it goes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1695975796020%2Fdef37d82-3628-4aff-a803-df449d9380c6.jpeg%2520align%3D" 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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1695975796020%2Fdef37d82-3628-4aff-a803-df449d9380c6.jpeg%2520align%3D" alt="Workmail Mobile Setup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1695975798612%2F9088e611-2c8d-495d-83f6-81fb98d98a95.jpeg%2520align%3D" 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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1695975798612%2F9088e611-2c8d-495d-83f6-81fb98d98a95.jpeg%2520align%3D" alt="Workmail on Mobile"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Access to the email also brings other features such as Calendar into our mobile app and we can use it as well as the email itself. Here's an example of how I create a reminder on the Calendar from the webmail client and mobile. Both will be synchronized automatically.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create Reminder from Webmail Client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fsamvokswribu69idhirx.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsamvokswribu69idhirx.png" alt="Workmail Calendar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fxn56i7lqc26ipkukpsu2.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxn56i7lqc26ipkukpsu2.jpg" alt="Workmail Calendar 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create Reminder from Mobile&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fmy38l1mwipltboun1btg.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmy38l1mwipltboun1btg.jpg" alt="Workmail Calendar 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Frvaxqscnx60i2rz5pkeh.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frvaxqscnx60i2rz5pkeh.png" alt="Workmail Calendar 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;We reach at the end of this post but it's not the end of this series. So please keep this state because we will use it again in the next post.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>workmail</category>
      <category>hosting</category>
      <category>cloud</category>
    </item>
    <item>
      <title>An Intro to Email Hosting World with Amazon Workmail</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Sat, 25 Mar 2023 08:45:06 +0000</pubDate>
      <link>https://dev.to/aws-builders/an-intro-to-email-hosting-world-with-amazon-workmail-3khn</link>
      <guid>https://dev.to/aws-builders/an-intro-to-email-hosting-world-with-amazon-workmail-3khn</guid>
      <description>&lt;p&gt;Hi everyone! Today I wanted to create a series, my third series to be exact. In this case, I wanted to talk about &lt;strong&gt;email&lt;/strong&gt;. Yes, email is one of the most important things for us. I think nowadays everyone has at least one email since anything is starting to go digital. Each has various purposes, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Personal: banking, digital IDs, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Business: e-commerce, customer support, communication with partners, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many more&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For personal purposes, you can create free email from some popular email providers. Why? Because you may not need a very big size of mailbox for some things like creating an account, verifying something, saving banking transactions or online shopping history. I think there are many email providers that give us pretty enough quota along with any other features such as calendar, notes, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BUT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When it comes to business, email is a very important thing and it's like being a part of a company's identity. You know, I've faced a lot of customer email issues and here I will share one of them which is a big deal and tell you in short.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain Spoofing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, a client almost lost their money because of the "attacker" using almost similar domain. For example, if the official domain is &lt;strong&gt;aws.com&lt;/strong&gt; then the "attacker" is using &lt;strong&gt;avvs.com&lt;/strong&gt;. So, it's very important to have a high level of accuracy. Other people may know what's our plan or our other business without realizing it. Then, they'll easily attack you since they already know what you &lt;strong&gt;have done&lt;/strong&gt;, &lt;strong&gt;are doing&lt;/strong&gt;, and &lt;strong&gt;will do&lt;/strong&gt;. So please be careful, especially for social engineering! This is just one of other many email issues.&lt;/p&gt;

&lt;p&gt;It's an unusual thing for a business or government company to use free email. I mean when we're looking for any information about a company, we will think about their official website and contact (email) in addition to phone number. So they should have their own official domain as a &lt;strong&gt;trusted identity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now let's talk about email services! When I think about AWS, Amazon SES came in my mind. Yes, I used to think that it was the only one :) but I wasn't completely wrong, right? As we all know, SES is a Simple Email Service. When we search &lt;strong&gt;AWS email services&lt;/strong&gt;, SES is on top for that keyword. But for daily transactions like sending and receiving emails, I prefer to use Amazon Workmail. I also don't see that using EC2 as a mail server is the best practice, considering that the associated ports are not allowed to be opened as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Amazon SES vs Workmail
&lt;/h2&gt;

&lt;p&gt;I won't compare them to get the &lt;strong&gt;best&lt;/strong&gt; service but I'm looking for the &lt;strong&gt;most suitable&lt;/strong&gt; service depending on our needs. SES is best for sending emails to those who subscribe to your apps like transactional or marketing emails, but it doesn't include POP or IMAP and I think that's enough for the reason why we don't use SES for email hosting. Since we are able to do that with Workmail, it's suitable for our case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Do We Choose Workmail and What Are The Benefits?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since I'm new to this service, I'll just mention some points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Only $4 for a 50GB mailbox per month.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get a free domain alias &lt;code&gt;subdomain.awsapps.com&lt;/code&gt; (in case you haven't bought domain) but if you have, you can use your own domain and all is under your control.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Webmail client is provided along with a calendar and contact as additional features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrated with Microsoft Exchange so you can set up email clients on your mobile and of course along with the calendar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For many more, click &lt;a href="https://aws.amazon.com/workmail/"&gt;here&lt;/a&gt;!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alright! I think it's enough for an introduction. In the next posts of this series, we will do more things with Amazon Workmail. I'll try my best to make it easy to follow so you can run your own email hosting for your business on AWS. Let's get started!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>workmail</category>
      <category>hosting</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Setting Up Amazon EC2 for Windows Server with Ansible</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Wed, 15 Feb 2023 11:18:27 +0000</pubDate>
      <link>https://dev.to/aws-builders/setting-up-amazon-ec2-for-windows-server-with-ansible-in3</link>
      <guid>https://dev.to/aws-builders/setting-up-amazon-ec2-for-windows-server-with-ansible-in3</guid>
      <description>&lt;p&gt;Hi everyone! I come back and this is my first post in 2023. I hope you are well, healthy, and still excited to keep learning.&lt;/p&gt;

&lt;p&gt;So, this post was created because someone asked me about his &lt;code&gt;user_data&lt;/code&gt; script for the Windows instance that didn't work. He's following my blog post &lt;a href="https://dev.to/aws-builders/launch-amazon-ec2-using-ansible-1mpf"&gt;here&lt;/a&gt; and there you can see my conversations with him as well. I think the case is an interesting and rare topic to be discussed, then here it is!&lt;/p&gt;

&lt;p&gt;To be honest, I've never launched a Windows EC2 instance as long as I learned AWS but at this time I do because I have to reproduce someone's case as I mentioned above. The reason actually doesn't sound cool :) but I hope it will be useful for anyone else who is in the same condition.&lt;/p&gt;

&lt;p&gt;Goal: Remote directly once the instance is running.&lt;/p&gt;

&lt;p&gt;Here are some steps we will do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create Key Pair&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Security Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retrieve Password&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remote&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As usual, if you are familiar with this blog. Before we do ansible tasks, you have to prepare some prerequisites:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html" rel="noopener noreferrer"&gt;set at least one credential&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html" rel="noopener noreferrer"&gt;Ansible&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ansible collection for AWS by running &lt;code&gt;ansible-galaxy collection install collection_name&lt;/code&gt;. There are 2 collections you can use, &lt;code&gt;amazon.aws&lt;/code&gt; and &lt;code&gt;community.aws&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Ready? Let's get started!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Create Key Pair&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I usually import a key pair for Linux instance but at this time I do something different. This is also the only requirement so we can retrieve the password for the Windows instance. Please note, that we only can use &lt;code&gt;rsa&lt;/code&gt; as a key type for Windows instances.&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="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="s"&gt;create rsa key pair&lt;/span&gt;
      &lt;span class="na"&gt;amazon.aws.ec2_key&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="s"&gt;Administrator&lt;/span&gt;
        &lt;span class="na"&gt;key_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rsa&lt;/span&gt;
      &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, let's save the file! We never know that we may need it again for future tasks. We can use it for any other Windows instances.&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="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="s"&gt;download private key&lt;/span&gt;
      &lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;content="{{ key.key.private_key }}" dest="administrator.pem" mode=0600&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create Security Group&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will create a custom SG that allows RDP port which is 3389.&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="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="s"&gt;create security group&lt;/span&gt;
      &lt;span class="na"&gt;amazon.aws.ec2_group&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="s"&gt;rdp&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;allow remote windows&lt;/span&gt;
        &lt;span class="na"&gt;vpc_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vpc-xxxx&lt;/span&gt;
        &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3&lt;/span&gt;
        &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;proto&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;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3389&lt;/span&gt;
            &lt;span class="na"&gt;cidr_ip&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;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sgroup&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Create Instance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here we will directly create one instance using &lt;code&gt;amazon.aws.ec2_instance&lt;/code&gt; module. Please check &lt;a href="https://dev.to/aws-builders/launch-amazon-ec2-using-ansible-1mpf"&gt;this blog post&lt;/a&gt; below for more.&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="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="s"&gt;create instance&lt;/span&gt;
      &lt;span class="na"&gt;amazon.aws.ec2_instance&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="s"&gt;windows&lt;/span&gt;
        &lt;span class="na"&gt;vpc_subnet_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;subnet-xxxx&lt;/span&gt;
        &lt;span class="na"&gt;image_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ami-019fd4e0ba82e7e28&lt;/span&gt;
        &lt;span class="na"&gt;instance_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;t3.micro&lt;/span&gt;
        &lt;span class="na"&gt;key_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;key.key.name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;security_group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;sgroup.group_id&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;
        &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;device_name&lt;/span&gt;&lt;span class="pi"&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;volume_size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
              &lt;span class="na"&gt;volume_type&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;delete_on_termination&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;user_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;lookup('file','script_file_name')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;wait&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;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;instance&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: &lt;code&gt;user_data&lt;/code&gt; is optional. In case you wanna use it with PowerShell. Don't forget to put your script between &lt;code&gt;powershell&lt;/code&gt; tag. It should seem like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;powershell&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$put_your_script_here&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;/powershell&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Retrieve Password&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here we ask default password for the default user of the Windows server which is the administrator.&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="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="s"&gt;get the Administrator password&lt;/span&gt;
      &lt;span class="na"&gt;community.aws.ec2_win_password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;instance_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;instance.instances[0].instance_id&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3&lt;/span&gt;
        &lt;span class="na"&gt;key_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;administrator.pem&lt;/span&gt;
        &lt;span class="na"&gt;wait&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;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&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="s"&gt;show password&lt;/span&gt;
      &lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;password.win_password&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's run the playbook!
&lt;/h2&gt;

&lt;p&gt;Here we run all tasks at once (in one YAML file) and refer the resources to each other as they are newly created (marked with register). All can be customized based on your need, either using variables, tags, or anything. For existing resources, you can directly define each resource's name as the value.&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;ansible-playbook &lt;span class="nt"&gt;-i&lt;/span&gt; host.yml windows.yml

PLAY &lt;span class="o"&gt;[&lt;/span&gt;windows] &lt;span class="k"&gt;*****************************************************************&lt;/span&gt;

TASK &lt;span class="o"&gt;[&lt;/span&gt;create rsa key pair] &lt;span class="k"&gt;*****************************************************&lt;/span&gt;
changed: &lt;span class="o"&gt;[&lt;/span&gt;127.0.0.1]

TASK &lt;span class="o"&gt;[&lt;/span&gt;download private key] &lt;span class="k"&gt;****************************************************&lt;/span&gt;
changed: &lt;span class="o"&gt;[&lt;/span&gt;127.0.0.1]

TASK &lt;span class="o"&gt;[&lt;/span&gt;create security group] &lt;span class="k"&gt;***************************************************&lt;/span&gt;
changed: &lt;span class="o"&gt;[&lt;/span&gt;127.0.0.1]

TASK &lt;span class="o"&gt;[&lt;/span&gt;create instance] &lt;span class="k"&gt;*********************************************************&lt;/span&gt;
changed: &lt;span class="o"&gt;[&lt;/span&gt;127.0.0.1]

TASK &lt;span class="o"&gt;[&lt;/span&gt;get the Administrator password] &lt;span class="k"&gt;******************************************&lt;/span&gt;
ok: &lt;span class="o"&gt;[&lt;/span&gt;127.0.0.1]

TASK &lt;span class="o"&gt;[&lt;/span&gt;show password] &lt;span class="k"&gt;***********************************************************&lt;/span&gt;
ok: &lt;span class="o"&gt;[&lt;/span&gt;127.0.0.1] &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"msg"&lt;/span&gt;: &lt;span class="s2"&gt;"baHNB1OIx8BL8;15&lt;/span&gt;&lt;span class="nv"&gt;$&amp;amp;&lt;/span&gt;&lt;span class="s2"&gt;*76xp.BNrp63DF"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

PLAY RECAP &lt;span class="k"&gt;*********************************************************************&lt;/span&gt;
127.0.0.1                  : &lt;span class="nv"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;6    &lt;span class="nv"&gt;changed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4    &lt;span class="nv"&gt;unreachable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0    &lt;span class="nv"&gt;failed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0    &lt;span class="nv"&gt;skipped&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0    &lt;span class="nv"&gt;rescued&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0    &lt;span class="nv"&gt;ignored&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Remote&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once all is ready, we can remote it using the RDP client. If you are a Linux user, you can use an RDP client for Linux such as Remmina.&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%2F41ienocrafws8qt85f69.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%2F41ienocrafws8qt85f69.png" alt="remmina_1" width="637" height="504"&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%2Fon50lirrj8otqm6sa3ht.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%2Fon50lirrj8otqm6sa3ht.png" alt="remmina_2" width="770" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all for now. Let me know if you have any questions or even corrections. Last but not least, don't forget to follow this blog! Thank you!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.ansible.com/ansible/latest/collections/community/aws/ec2_win_password_module.html" rel="noopener noreferrer"&gt;https://docs.ansible.com/ansible/latest/collections/community/aws/ec2_win_password_module.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://aws.amazon.com/premiumsupport/knowledge-center/retrieve-windows-admin-password/" rel="noopener noreferrer"&gt;https://aws.amazon.com/premiumsupport/knowledge-center/retrieve-windows-admin-password/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html#user-data-powershell" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html#user-data-powershell&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>More Automation for Your AWS Resources, More Coffee Time for You!</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Sun, 30 Oct 2022 05:34:08 +0000</pubDate>
      <link>https://dev.to/aws-builders/more-automation-for-your-aws-resources-more-coffee-time-for-you-53hb</link>
      <guid>https://dev.to/aws-builders/more-automation-for-your-aws-resources-more-coffee-time-for-you-53hb</guid>
      <description>&lt;p&gt;Hi everyone! It's been a while since my latest post (2 months ago) but today I have an interesting topic to discuss. Actually, I already talked about this topic at the AWS UG Indonesia event but the session was in Indonesian (&lt;a href="https://www.youtube.com/watch?v=6azgWVegTgU"&gt;here's the video&lt;/a&gt;) so I thought about turning it into a blog post in English.&lt;/p&gt;

&lt;p&gt;Alright! You may see that mostly I talked about Ansible for AWS on this blog, but at this time I'll talk on the other side about where we can combine them. They can actually be "friends" and shouldn't always be comparisons. These works can help you to do more automation for your AWS resources which means that you will have more time to enjoy your coffee :) I mean everybody loves it, right?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--poVXgYXn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xlzdadlpjre0mmffpz7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--poVXgYXn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xlzdadlpjre0mmffpz7z.png" alt="AWS Ansible Automation" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"&gt;AWS CLI&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html"&gt;set at least one credential&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html"&gt;Ansible&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ansible collection for AWS by running &lt;code&gt;ansible-galaxy collection install amazon.aws&lt;/code&gt; and &lt;code&gt;ansible-galaxy collection install community.aws&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Dynamic Inventory For EC2 Instances
&lt;/h2&gt;

&lt;p&gt;Yes, we usually manage our server inventory manually which we input the IP addresses or hostnames manually like below:&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;ec2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;108.136.226.235&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;108.136.226.232&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;108.136.226.238&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But Ansible has a plugin that enables us to manage our EC2 instances and meets our needs. It's very easy to do, simple and you will get what you want in a short time.&lt;/p&gt;

&lt;p&gt;To use this plugin, below are the steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new YAML file and input the code below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;plugin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws_ec2&lt;/span&gt;
&lt;span class="na"&gt;regions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3&lt;/span&gt;
&lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;availability-zone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will enable us to get the EC2 details and create a group for our instances based on the filter we use. For example above, I need to manage EC2 instances in the Jakarta region and I added a filter AZ because I just need to manage the instances in the AZ B. Any filter we can use is just the same as we use the EC2 filter by AWS CLI (if we can use the filter using AWS CLI EC2, then we can use it too on this plugin).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After creating the file, run the 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="nv"&gt;$ &lt;/span&gt;ansible-inventory &lt;span class="nt"&gt;-i&lt;/span&gt; aws_ec2.yml &lt;span class="nt"&gt;--list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the sample output:&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="s2"&gt;"aws_ec2"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"hosts"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"ec2-108-136-56-235.ap-southeast-3.compute.amazonaws.com"&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If we just wanna see the grouping, run the 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="nv"&gt;$ &lt;/span&gt;ansible-inventory &lt;span class="nt"&gt;-i&lt;/span&gt; aws_ec2.yml &lt;span class="nt"&gt;--graph&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the sample output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;@all
  |--@aws_ec2:
  |  |--ec2-108-136-56-235.ap-southeast-3.compute.amazonaws.com
  |--@ungrouped:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In case we wanna run some command or playbook to our instances for example to install an application on them, we can mention the inventory just like we use Ansible as usual. Below is a sample by running ansible ad-hoc and we will see the output when it's done.
&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;ansible &lt;span class="nt"&gt;-i&lt;/span&gt; aws_ec2.yml &lt;span class="nt"&gt;-u&lt;/span&gt; ubuntu &lt;span class="nt"&gt;-m&lt;/span&gt; shell &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"sudo apt install apache2 -y"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we all see, how easy is for us to manage our EC2 instances. More about this plugin, you can find it &lt;a href="https://docs.ansible.com/ansible/latest/collections/amazon/aws/aws_ec2_inventory.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Running AWS CloudFormation using Ansible
&lt;/h2&gt;

&lt;p&gt;In this concept, we automate the AWS IaC tool. As we all know, CloudFormation gives us an easy way for infrastructure provisioning on AWS into a file, just by pushing a template. That sounds great, right? But do you know that Ansible has a module for that?&lt;/p&gt;

&lt;p&gt;Yup! Ansible has and we can get some benefits by combining them. As I mentioned before, they shouldn't always be comparisons but it will be better to run them together.&lt;/p&gt;

&lt;p&gt;What can we do with them?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create multiple stacks at once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In case we wanna create some stacks with the same resources along with their own values, we can do that with Ansible. We don't need to copy-paste the same template just for the same resources. All we need to do is just turn it into a variable. Let's see how it works!&lt;/p&gt;

&lt;p&gt;Here's the sample task that we can use. The key is the &lt;code&gt;template_body&lt;/code&gt; argument which allows us to use the jinja2 template. In this case, I wanna create a bucket in two stacks and each stack has its own stack name and the bucket name as well. So in the &lt;code&gt;stack1,&lt;/code&gt; I wanna create a bucket named &lt;code&gt;nuruls3&lt;/code&gt; and for the &lt;code&gt;stack2&lt;/code&gt;, the bucket name is &lt;code&gt;dhonas3&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="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="s"&gt;create cloudformation stacks&lt;/span&gt;
      &lt;span class="na"&gt;amazon.aws.cloudformation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;stack_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;item.name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;
        &lt;span class="na"&gt;template_body&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;lookup('template',&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'cf-template.yml.j2')&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
      &lt;span class="na"&gt;loop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;stack1&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;bucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;nuruls3&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;stack2&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;bucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;dhonas3&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What does the template look like? It's just as simple as this. We turn the bucket name which the data type is string into a variable.&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;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;S3Bucket&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="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AWS::S3::Bucket'&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;BucketName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;item.bucket&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So when we wanna define different values for different stacks using one (same) template, we just need to change the variables under the loop action.&lt;/p&gt;

&lt;p&gt;Here's the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;TASK &lt;span class="o"&gt;[&lt;/span&gt;create a cloudformation stack] &lt;span class="k"&gt;*******************************************&lt;/span&gt;
changed: &lt;span class="o"&gt;[&lt;/span&gt;localhost] &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;: &lt;span class="s1"&gt;'stack1'&lt;/span&gt;, &lt;span class="s1"&gt;'bucket'&lt;/span&gt;: &lt;span class="s1"&gt;'nuruls3'&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
changed: &lt;span class="o"&gt;[&lt;/span&gt;localhost] &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;: &lt;span class="s1"&gt;'stack2'&lt;/span&gt;, &lt;span class="s1"&gt;'bucket'&lt;/span&gt;: &lt;span class="s1"&gt;'dhonas3'&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DQcHfkYS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ypkbbe5f989efqx6c8r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DQcHfkYS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ypkbbe5f989efqx6c8r.png" alt="CloudFormation Stacks Created By Ansible" width="800" height="121"&gt;&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;aws s3 &lt;span class="nb"&gt;ls
&lt;/span&gt;2022-10-30 11:08:19 dhonas3
2022-10-30 11:07:51 nuruls3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: We can also update and delete as well as the creation. More about this module, click &lt;a href="https://docs.ansible.com/ansible/latest/collections/amazon/aws/cloudformation_module.html"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a stack that contains resources in different accounts (in case you have more than one).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a sample from the Ansible documentation:&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="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="s"&gt;Create a stack set with instances in two accounts&lt;/span&gt;
  &lt;span class="na"&gt;community.aws.cloudformation_stack_set&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="s"&gt;my-stack&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;Test stack in two accounts&lt;/span&gt;
    &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;
    &lt;span class="na"&gt;template_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://s3.amazonaws.com/my-bucket/cloudformation.template&lt;/span&gt;
    &lt;span class="na"&gt;accounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;1234567890&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;2345678901&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;regions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On this step, I'm not able to reproduce it because I just have one account and I think I don't need to create a new one just to do this :) it's enough for me to have one because it's just for personal use but in case you need to use it because you have more than one account, please let me give you some tips. For me, instead of using &lt;code&gt;template_url&lt;/code&gt; which you have to upload on the S3 bucket, you can use &lt;code&gt;template_body&lt;/code&gt;. Why? Because you will be able to do something more flexible. For example, you can use the jinja2 template where you can freely customize the parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Running Ansible from AWS Systems Manager
&lt;/h2&gt;

&lt;p&gt;SSM is a great thing to use to manage our EC2 instances and the good thing is we can run the Ansible playbook from SSM.&lt;/p&gt;

&lt;p&gt;All we need to do is just to attach IAM role on the EC2 instances you want to manage that allows them to communicate with SSM or we can say to make the SSM-Agent installed on the EC2 instances work. Yup! For the latest AMI, SSM-Agent has already been installed by default so we don't need to install it again (check the full information &lt;a href="https://docs.amazonaws.cn/en_us/systems-manager/latest/userguide/ami-preinstalled-agent.html"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;One more thing we need to do is install Ansible on our EC2 instances because it will be running on your instances which acts as an Ansible host, that's why it should be installed. (This action can be done by SSM as well as by SSM RunCommand but in this case we use Shell).&lt;/p&gt;

&lt;p&gt;Here we will use RunCommand with the document &lt;code&gt;RunAnsiblePlaybook&lt;/code&gt; from Systems Manager and AFAIK it's free to do RunCommand so it can be one of your alternatives to run Ansible instead of using your localhost.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n53jdKW7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1wk6xpd83ox6gywcdizp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n53jdKW7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1wk6xpd83ox6gywcdizp.png" alt="AWS SSM RunCommand" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a sample of the playbook. You can directly write it into the column provided or use the URL where you store your playbook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sL5sPBHH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a63rb8dudco80dwh9uto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sL5sPBHH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a63rb8dudco80dwh9uto.png" alt="AWS SSM RunAnsiblePlaybook" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case you wanna run it using AWS CLI, below is the sample:&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;aws ssm send-command &lt;span class="nt"&gt;--document-name&lt;/span&gt; &lt;span class="s2"&gt;"AWS-RunAnsiblePlaybook"&lt;/span&gt; &lt;span class="nt"&gt;--document-version&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt; &lt;span class="nt"&gt;--targets&lt;/span&gt; &lt;span class="s1"&gt;'[{"Key":"InstanceIds","Values":[your-instances-ids]}]'&lt;/span&gt; &lt;span class="nt"&gt;--parameters&lt;/span&gt; &lt;span class="s1"&gt;'{"playbook":["hosts: localhost\ntasks:\n - name: install web server\n apt: name=apache2"],"playbookurl":[""],"extravars":["SSM=True"],"check":["False"],"timeoutSeconds":["3600"]}'&lt;/span&gt; &lt;span class="nt"&gt;--timeout-seconds&lt;/span&gt; 600 &lt;span class="nt"&gt;--max-concurrency&lt;/span&gt; &lt;span class="s2"&gt;"50"&lt;/span&gt; &lt;span class="nt"&gt;--max-errors&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright! Those are three cool things we can do with Ansible to automate our AWS resources. I hope they can help you extend your time enjoying the coffee :) instead of spending more time working for your system (just let them work for you).&lt;/p&gt;

&lt;p&gt;That's it for now! Thank you for coming and I'm looking forward to your feedback. Follow me to get notified when my new post is published!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ansible</category>
      <category>cloudformation</category>
      <category>ssm</category>
    </item>
    <item>
      <title>Trying New RDS Feature: Connectivity with EC2 in 1-Click?</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Thu, 25 Aug 2022 03:33:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/trying-new-rds-feature-connectivity-with-ec2-in-1-click-3gb4</link>
      <guid>https://dev.to/aws-builders/trying-new-rds-feature-connectivity-with-ec2-in-1-click-3gb4</guid>
      <description>&lt;p&gt;Have you noticed that RDS has a new feature? Yup! 3 days ago AWS announced that now RDS supports setting up connectivity between RDS and EC2 &lt;strong&gt;only in 1 click&lt;/strong&gt;. We don't need to prepare VPC, subnets, security groups, etc. Wow! That sounds great, right? &lt;strong&gt;But&lt;/strong&gt; some "T&amp;amp;Cs" are applied to make this feature work properly. How does it work?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wuhZGL97--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pt18gjkbpuci4n1tnwix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wuhZGL97--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pt18gjkbpuci4n1tnwix.png" alt="RDS EC2 Connectivity" width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case you want more information about new features, you can visit &lt;a href="https://aws.amazon.com/new"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By the way, I did all of these following practices via Console because I still can't find the &lt;a href="https://awscli.amazonaws.com/v2/documentation/api/latest/reference/rds/index.html"&gt;CLI option&lt;/a&gt; for this feature maybe because it just launched (CMIIW and tell me in the comment if you know any information about this). I'm sorry if you will see a bunch of images below :)&lt;/p&gt;

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

&lt;p&gt;The minimum network prefix (CIDR) per subnet is &lt;strong&gt;/24&lt;/strong&gt; to create the RDS DB instance &lt;strong&gt;in the same VPC&lt;/strong&gt; as the EC2 instance.&lt;/p&gt;

&lt;p&gt;For example in this case I'll be creating RDS in the Jakarta region (ap-southeast-3) which has 3 AZs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DxhS-_Tm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wklg4wlwatpe7jj6e0sn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DxhS-_Tm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wklg4wlwatpe7jj6e0sn.png" alt="RDS TNC" width="791" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on &lt;strong&gt;my experience&lt;/strong&gt; in "trying" this feature 2 days ago, I found some stuff you may need to know. Here we will play some scenarios, so we can be more understanding about this feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Using Custom VPC With CIDR /22
&lt;/h2&gt;

&lt;p&gt;Here I use &lt;code&gt;/22&lt;/code&gt; because it's enough to create a subnet with &lt;code&gt;/24&lt;/code&gt; for each AZ (total 3). &lt;code&gt;/22&lt;/code&gt; can be divided into 4 pieces of &lt;code&gt;/24&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Below is the diagram when I only created 1 public subnet in 1 AZ for EC2 instance before creating RDS and 2 more AZs don't have subnet yet. From this condition, 3 idle &lt;code&gt;/24&lt;/code&gt; is available and enough to be used by RDS to create one subnet with &lt;code&gt;/24&lt;/code&gt; in each AZ.&lt;/p&gt;

&lt;p&gt;Note: In this case, I used the Free Tier template which Multi-AZ is disabled because it's just for personal testing purposes. That's why the automated backup is created in the same AZ and a stand-by instance is not created. You can use Dev/Test or Production to make those options enabled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xFhxLP9Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/295s7slv030rzbjp5pyq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xFhxLP9Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/295s7slv030rzbjp5pyq.png" alt="RDS + Snapshot" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What did RDS create?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 subnet in each AZ (total 3 subnets for 3 AZs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8lzHThzN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrq0u6oqptos9hit29ug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8lzHThzN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrq0u6oqptos9hit29ug.png" alt="3 subnets" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 security groups (allow 3306 from EC2 to RDS) and both are linked to each other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qdtMjGub--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s618a5rxbftedcw46l7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qdtMjGub--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s618a5rxbftedcw46l7i.png" alt="SG 1" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x23-PIj1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/70l1hhvqv1i7an0kpte4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x23-PIj1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/70l1hhvqv1i7an0kpte4.png" alt="SG 2" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 RDS instance and its automated backup successfully created&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y-otgEup--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqincd8jjex9sw0a53rw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y-otgEup--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqincd8jjex9sw0a53rw.png" alt="Instance + Snapshot" width="800" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G1Lw2ksZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hupkmhz78w1q0d07i5cw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G1Lw2ksZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hupkmhz78w1q0d07i5cw.png" alt="RDS endpoint" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RPCeEXJ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cb8vcv17cqcgh27y4pmb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RPCeEXJ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cb8vcv17cqcgh27y4pmb.png" alt="RDS EC2 Connected Successfully" width="640" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Using Default VPC
&lt;/h2&gt;

&lt;p&gt;In this case, the connectivity should be successfully established because it has a CIDR that big enough to create a new subnet &lt;code&gt;/24&lt;/code&gt; in each AZ for RDS which is &lt;code&gt;/16&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_DEu-YYk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/myp0078bt8mja68ux5yn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_DEu-YYk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/myp0078bt8mja68ux5yn.png" alt="Default VPC" width="471" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xg6ntfe1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3jt026cts1gilhu949d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xg6ntfe1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3jt026cts1gilhu949d.png" alt="RDS VPC Default" width="641" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Using Custom VPC With CIDR Smaller Than /22
&lt;/h2&gt;

&lt;p&gt;The result is a failure. Why? Because &lt;code&gt;/23&lt;/code&gt; only can be divided into 2 &lt;code&gt;/24&lt;/code&gt;. See the following diagram!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---EPGq71_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xdnjo6f7zr5vba0qd8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---EPGq71_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xdnjo6f7zr5vba0qd8f.png" alt="RDS EC2 Failed" width="471" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YntXtd5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9oj6hx48pkhqa8edgvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YntXtd5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9oj6hx48pkhqa8edgvv.png" alt="RDS Connectivity Failed" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, the RDS DB instance is still created but it's using default VPC which is in a different subnet from EC2.&lt;/p&gt;

&lt;p&gt;2 new security groups are also created by RDS for the new VPC but only the security group for EC2 is properly attached because RDS is using default subnet group of the default VPC which is a specific rule that is not configured to allow incoming traffic from EC2 port 3306 to RDS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cr5K6wnK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axzy7agqng9lvc230z7l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cr5K6wnK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axzy7agqng9lvc230z7l.png" alt="RDS Default SG" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Te8oVuii--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhmef8b0xja3m53rdx38.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Te8oVuii--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhmef8b0xja3m53rdx38.png" alt="RDS Connectivity Failed" width="641" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Q: &lt;strong&gt;Then, how to make it work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A: We can't do that because we can't change VPC of both RDS and EC2&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;but&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you followed my scenario number 2, it created an EC2 instance and RDS in the same VPC which is the default VPC and it already has 2 security groups created by RDS. So in this case, all we can do is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;"Move" EC2 instance to the default VPC where RDS is placed. You can create a new AMI from the existing EC2 instance or create a new instance. At this time, I'll use the EC2 instance that was created in scenario number 2 which is placed in default VPC and the security group created by RDS is already attached to the EC2 instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the current RDS DB subnet group to other subnet groups &lt;strong&gt;in the same VPC&lt;/strong&gt;. In this case, it's the default VPC that was created in scenario number 2.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tjg-8LnM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xx3pyd940uq1nltq0mep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tjg-8LnM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xx3pyd940uq1nltq0mep.png" alt="Default SG" width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--slkTK9SE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7orktdnpmlx7mb1rm52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--slkTK9SE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7orktdnpmlx7mb1rm52.png" alt="Change SG" width="197" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aj5fDgZo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0s6kvw1j8wnewqy6ylj8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aj5fDgZo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0s6kvw1j8wnewqy6ylj8.png" alt="Connected After Change SG" width="640" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, we are done with all the scenarios!&lt;/p&gt;

&lt;h2&gt;
  
  
  Clean Up
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Scenario 1&lt;/strong&gt; (Custom VPC)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Delete the RDS DB instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the RDS DB subnet group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Terminate the EC2 instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the VPC&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Scenario 2&lt;/strong&gt; (Default VPC)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Delete the RDS DB instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the RDS DB subnet group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Terminate the EC2 instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete security groups created by RDS (please delete rules that associated with each other before deleting them)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the route table for subnets created by RDS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the subnets created by RDS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Scenario 3&lt;/strong&gt; (same as Scenario 1)&lt;/p&gt;

&lt;p&gt;That's it for now! Thank you for coming and I'm looking forward to your feedback. Follow me to get notified when my new post is published!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>rds</category>
      <category>database</category>
      <category>cloud</category>
    </item>
    <item>
      <title>AWS Auto Scaling Features to Optimize Cost and Ensure Availability</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Thu, 18 Aug 2022 07:24:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/aws-auto-scaling-features-to-optimize-cost-and-ensure-availability-3c8l</link>
      <guid>https://dev.to/aws-builders/aws-auto-scaling-features-to-optimize-cost-and-ensure-availability-3c8l</guid>
      <description>&lt;p&gt;Cloud Computing may be a solution for your on-premises problem but not everyone knows the cloud, right? Let's say you find a solution for your application that can be done using the cloud but a solution to "&lt;em&gt;persuade&lt;/em&gt;" your boss may seem a bit harder :)&lt;/p&gt;

&lt;p&gt;If you agree with me, please comment "Yes" so I can hear your voice :) &lt;em&gt;Just kidding!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Are you the one who is confused with so many questions?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;How about the cost? (we can't deny that it always be number one)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What are the benefits?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many more ...&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following solutions can be your "&lt;em&gt;weapon&lt;/em&gt;" when it comes to the cloud, but how?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fakjwtkd31g64sxobw704.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakjwtkd31g64sxobw704.png" alt="EC2 Auto Scaling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Always Available
&lt;/h2&gt;

&lt;p&gt;One of the biggest benefits of using the cloud is the provider is always able to meet our needs. Let's say you need a VM right now! You can directly access your AWS console and create an EC2 instance. It will be available and running as soon as possible after you create it. One problem is solved.&lt;/p&gt;

&lt;p&gt;Then, what if we need more features? Let's say you want to use LightSail to run your WordPress instantly but it seems like it's not available in your region (for example Jakarta)! You can choose the nearest region where the service is already activated (for example Singapore). The second problem is solved and you can access your WordPress dashboard now.&lt;/p&gt;

&lt;p&gt;Or maybe you want to have a backup for your application when there is a problem in one area? You can activate multi-AZ or region, third problem is solved.&lt;/p&gt;

&lt;p&gt;But what if our product/application becomes viral and accessed from various countries? You can use CloudFront as CDN.&lt;/p&gt;

&lt;p&gt;That's how cloud availability solves our problem "&lt;strong&gt;in general&lt;/strong&gt;", I can't say it's the best AWS solution since AWS has so many services. So when we need the resources as soon as possible, we don't need to buy and look for the best brand for our devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ease of Scaling
&lt;/h2&gt;

&lt;p&gt;Let's say we're newbies in the cloud and we're just moving from on-premises culture. So EC2 will bring you easily to get to know about cloud environment. We all know we can create as many EC2 instances as we need (20 per region but can be increased by request) but one thing that really important and we can't forget about is &lt;strong&gt;cost&lt;/strong&gt;. It can be so high when you don't know how to optimize based on your need (especially when you use on-demand instances).&lt;/p&gt;

&lt;p&gt;Alright! There are so many ways we can scale our applications and optimize the cost, but here I will take two services that can be a basis for how we do it with AWS.&lt;/p&gt;

&lt;p&gt;In this post, I'll create AWS Auto Scaling Group and Application Load Balancer using CloudFormation. All operations will be done through CLI, so make sure you have installed &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html" rel="noopener noreferrer"&gt;set up the credentials&lt;/a&gt;. Note: You can do this through the web console if you want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzwr5fh6thcioe1np3brp.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzwr5fh6thcioe1np3brp.png" alt="Full ASG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Network details (you can change based on your need):&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;VPC CIDR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;172.16.0.0/16&lt;/span&gt;
&lt;span class="na"&gt;Subnet 1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;172.16.1.0/28&lt;/span&gt;
&lt;span class="na"&gt;Subnet 2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;172.16.15.0/28&lt;/span&gt; 
&lt;span class="na"&gt;Subnet 3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;172.16.30.0/28&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Sorry for a little typo, subnet 2 should be &lt;code&gt;172.16.1.16/28&lt;/code&gt; and subnet 3 should be &lt;code&gt;172.16.1.32/28&lt;/code&gt; for &lt;code&gt;/28&lt;/code&gt; usage but it's okay because the above networks still work)&lt;/p&gt;

&lt;p&gt;Here's the whole content of the CloudFormation template named &lt;code&gt;cfn-asg.yaml&lt;/code&gt;! I'll tell you the main points later.&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;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2010-09-09&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;AmazonLinux2LatestAmiId&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::SSM::Parameter::Value&amp;lt;AWS::EC2::Image::Id&amp;gt;&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;/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2&lt;/span&gt;
  &lt;span class="na"&gt;EnvironmentName&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;DhonaASGTemplate&lt;/span&gt;
  &lt;span class="na"&gt;SpotInstanceType1&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;t3.large&lt;/span&gt;
  &lt;span class="na"&gt;SpotInstanceType2&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;t3.medium&lt;/span&gt;
  &lt;span class="na"&gt;SpotInstanceType3&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;t3.small&lt;/span&gt;
  &lt;span class="na"&gt;SpotInstanceType4&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;t3.micro&lt;/span&gt;
  &lt;span class="na"&gt;SpotInstanceType5&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;t3.nano&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="s"&gt;172.16.0.0/16&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="na"&gt;Fn::Sub&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${EnvironmentName}&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="na"&gt;Fn::Sub&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${EnvironmentName}&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&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="na"&gt;Fn::Sub&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${EnvironmentName} Public Routes&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;InternetGateway&lt;/span&gt;
  &lt;span class="na"&gt;PublicSubnet1RouteTableAssociation&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet1&lt;/span&gt;
  &lt;span class="na"&gt;PublicSubnet1&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;VPC&lt;/span&gt;
      &lt;span class="na"&gt;AvailabilityZone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3a&lt;/span&gt;
      &lt;span class="na"&gt;CidrBlock&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;172.16.1.0/28&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="na"&gt;Fn::Sub&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${EnvironmentName} Public Subnet (AZ1)&lt;/span&gt;
  &lt;span class="na"&gt;PublicSubnet2RouteTableAssociation&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet2&lt;/span&gt;
  &lt;span class="na"&gt;PublicSubnet2&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;VPC&lt;/span&gt;
      &lt;span class="na"&gt;AvailabilityZone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3b&lt;/span&gt;
      &lt;span class="na"&gt;CidrBlock&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;172.16.15.0/28&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="na"&gt;Fn::Sub&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${EnvironmentName} Public Subnet (AZ2)&lt;/span&gt;
  &lt;span class="na"&gt;PublicSubnet3RouteTableAssociation&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet3&lt;/span&gt;
  &lt;span class="na"&gt;PublicSubnet3&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;VPC&lt;/span&gt;
      &lt;span class="na"&gt;AvailabilityZone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3c&lt;/span&gt;
      &lt;span class="na"&gt;CidrBlock&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;172.16.30.0/28&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="na"&gt;Fn::Sub&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${EnvironmentName} Public Subnet (AZ3)&lt;/span&gt;

  &lt;span class="na"&gt;DhonaWebAppAutoScalingGroup&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::AutoScaling::AutoScalingGroup&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;CapacityRebalance&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;HealthCheckType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ELB&lt;/span&gt;
      &lt;span class="na"&gt;HealthCheckGracePeriod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;
      &lt;span class="na"&gt;MinSize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;
      &lt;span class="na"&gt;MaxSize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5"&lt;/span&gt;
      &lt;span class="na"&gt;DesiredCapacity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;
      &lt;span class="na"&gt;VPCZoneIdentifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet1&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet2&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet3&lt;/span&gt;
      &lt;span class="na"&gt;MixedInstancesPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;InstancesDistribution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;OnDemandAllocationStrategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prioritized&lt;/span&gt;
          &lt;span class="na"&gt;OnDemandPercentageAboveBaseCapacity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
          &lt;span class="na"&gt;SpotAllocationStrategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;capacity-optimized&lt;/span&gt;
          &lt;span class="na"&gt;SpotMaxPrice&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.003&lt;/span&gt;
        &lt;span class="na"&gt;LaunchTemplate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;LaunchTemplateSpecification&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;LaunchTemplateId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppLaunchTemplate&lt;/span&gt;
            &lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;Fn::GetAtt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppLaunchTemplate&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;LatestVersionNumber&lt;/span&gt;
          &lt;span class="na"&gt;Overrides&lt;/span&gt;&lt;span class="pi"&gt;:&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType1&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType2&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType3&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType4&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType5&lt;/span&gt;
      &lt;span class="na"&gt;TargetGroupARNs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppTargetGroup&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="na"&gt;Fn::Sub&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${EnvironmentName}&lt;/span&gt;
          &lt;span class="na"&gt;PropagateAtLaunch&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;DhonaWebAppLaunchTemplate&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::LaunchTemplate&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;LaunchTemplateData&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AmazonLinux2LatestAmiId&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppEC2SecurityGroup&lt;/span&gt;
        &lt;span class="na"&gt;UserData&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Fn::Base64&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="s"&gt;#!/bin/bash&lt;/span&gt;

            &lt;span class="s"&gt;yum -y install httpd&lt;/span&gt;

            &lt;span class="s"&gt;echo "hello world! &lt;/span&gt;

            &lt;span class="s"&gt;My instance-id is $(curl -s http://169.254.169.254/latest/meta-data/instance-id)&lt;/span&gt;

            &lt;span class="s"&gt;My instance type is $(curl -s http://169.254.169.254/latest/meta-data/instance-type)&lt;/span&gt;

            &lt;span class="s"&gt;I'm on Availability Zone $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)" &amp;gt; /var/www/html/index.html&lt;/span&gt;

            &lt;span class="s"&gt;service httpd start&lt;/span&gt;
  &lt;span class="na"&gt;DhonaWebAppELBSecurityGroup&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="s"&gt;Security group for ELB&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;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;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;VpcId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;VPC&lt;/span&gt;
  &lt;span class="na"&gt;DhonaWebAppEC2SecurityGroup&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="s"&gt;Security group for EC2 ASG&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;SourceSecurityGroupId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppELBSecurityGroup&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;VpcId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;VPC&lt;/span&gt;
  &lt;span class="na"&gt;DhonaWebAppLoadBalancer&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::ElasticLoadBalancingV2::LoadBalancer&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;SecurityGroups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppELBSecurityGroup&lt;/span&gt;
      &lt;span class="na"&gt;Subnets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet1&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet2&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublicSubnet3&lt;/span&gt;
  &lt;span class="na"&gt;DhonaWebAppTargetGroup&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::ElasticLoadBalancingV2::TargetGroup&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;Port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80"&lt;/span&gt;
      &lt;span class="na"&gt;Protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HTTP&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;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;VPC&lt;/span&gt;
  &lt;span class="na"&gt;ALBListener&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::ElasticLoadBalancingV2::Listener&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;LoadBalancerArn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppLoadBalancer&lt;/span&gt;
      &lt;span class="na"&gt;Port&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;Protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HTTP&lt;/span&gt;
      &lt;span class="na"&gt;DefaultActions&lt;/span&gt;&lt;span class="pi"&gt;:&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;forward&lt;/span&gt;
          &lt;span class="na"&gt;TargetGroupArn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppTargetGroup&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;URL&lt;/span&gt;&lt;span class="pi"&gt;:&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;!Join&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://'&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppLoadBalancer&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DNSName&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create the CloudFormation stack!&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;aws cloudformation create-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; cfn-asg &lt;span class="nt"&gt;--template-body&lt;/span&gt; file://cfn-asg.yaml
StackId: arn:aws:cloudformation:ap-southeast-3:0123456789:stack/cfn-asg/438781a0-1e7e-11ed-b1ba-06ff26b14cdc
&lt;span class="nv"&gt;$ &lt;/span&gt;aws cloudformation describe-stacks &lt;span class="nt"&gt;--stack-name&lt;/span&gt; cfn-asg | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"OutputValue&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;StackStatus"&lt;/span&gt;
    OutputValue: http://cfn-a-Dhona-1NM3JA9AKJ0BE-1240836435.ap-southeast-3.elb.amazonaws.com
  StackStatus: CREATE_COMPLETE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Main Points
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Use Mixed Instances (On-Demand + Spot) To Optimize Cost&lt;/strong&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;MixedInstancesPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;InstancesDistribution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;OnDemandAllocationStrategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prioritized&lt;/span&gt;
          &lt;span class="na"&gt;OnDemandPercentageAboveBaseCapacity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
          &lt;span class="na"&gt;SpotAllocationStrategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;capacity-optimized&lt;/span&gt;
          &lt;span class="na"&gt;SpotMaxPrice&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.003&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your workload can be interrupted (the process can be repeated when it fails), you can use spot instances. Why? Because you will get a big discount instead of using On-Demand. Here's the comparison:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F8mbkgsn1vhkw2s6i2ibt.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8mbkgsn1vhkw2s6i2ibt.png" alt="Pricing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, it's almost 70% compared to the On-Demand instance but one thing you should know is it can be interrupted when your bid price is lower than the actual price. That's why you should know which workloads are suitable for this instance type.&lt;/p&gt;

&lt;p&gt;Then here I use 5 instance types based on priority:&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;Overrides&lt;/span&gt;&lt;span class="pi"&gt;:&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType1 (t3.large)&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType2 (t3.medium)&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType3 (t3.small)&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType4 (t3.micro)&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="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SpotInstanceType5 (t3.nano)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pricing:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Flabqgjkp9ii7c04mnpuj.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flabqgjkp9ii7c04mnpuj.png" alt="Priority"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the details above, I choose to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;On-demand instance type based on top priority (t3.large) with percentage 30 which means 30% on-demand and 70% for spot instances. So if I use desired and minimum capacity 3, 1 on-demand instance and 2 spot instances should be running.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Spot instances with a maximum price is 0.003 and based on all instance types I used, t3.nano meets the criteria.&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="nv"&gt;$ &lt;/span&gt;aws ec2 describe-instances &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;instance-state-name,Values&lt;span class="o"&gt;=&lt;/span&gt;running &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Reservations[].Instances[].{ID:InstanceId}'&lt;/span&gt;
- ID: i-02323c2a2be9759f2
- ID: i-004b63ceec33e2bb5
- ID: i-0b11803cfd9e623bb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the settings, the first creation of this architecture is going to be:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fcvxdiixyhjxl851at6sy.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvxdiixyhjxl851at6sy.png" alt="ASG 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fdl8qat51lpv5zzui43dd.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl8qat51lpv5zzui43dd.png" alt="Output 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Activate Capacity Rebalance To Ensure Availability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It helps you to create a new spot instance based on the EC2 instance rebalance recommendation two minutes before your current spot instance is interrupted.&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;CapacityRebalance&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information, click &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-capacity-rebalancing.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Use Launch Template Instead of Launch Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fce2ocimmpj6rzcwcz0n5.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fce2ocimmpj6rzcwcz0n5.png" alt="Launch Template"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more information, click &lt;a href="https://aws.amazon.com/blogs/compute/amazon-ec2-auto-scaling-will-no-longer-add-support-for-new-ec2-features-to-launch-configurations/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Alright! Those are all the main points. Let's play some scenarios so we can understand them better!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Change Maximum Spot Price (Increase)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the first change, we will increase the maximum spot price and terminate one spot instance to see which instance type will be chosen.&lt;/p&gt;

&lt;p&gt;Note: You can make a change to the same template directly. Here I create a new template to show you the difference between them.&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;diff cfn-asg.yaml cfn-asg-2.yaml 
145c145
&amp;lt;           SpotMaxPrice: 0.003
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;           SpotMaxPrice: 0.01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the stack:&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;aws cloudformation update-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; cfn-asg &lt;span class="nt"&gt;--template-body&lt;/span&gt; file://cfn-asg-2.yaml
StackId: arn:aws:cloudformation:ap-southeast-3:0123456789:stack/cfn-asg/438781a0-1e7e-11ed-b1ba-06ff26b14cdc
&lt;span class="nv"&gt;$ &lt;/span&gt;aws cloudformation describe-stacks &lt;span class="nt"&gt;--stack-name&lt;/span&gt; cfn-asg | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"OutputValue&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;StackStatus"&lt;/span&gt;
    OutputValue: http://cfn-a-Dhona-1NM3JA9AKJ0BE-1240836435.ap-southeast-3.elb.amazonaws.com
  StackStatus: UPDATE_COMPLETE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terminate one spot instance:&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;aws ec2 describe-spot-instance-requests &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"SpotInstanceRequests[*].{ID:InstanceId}"&lt;/span&gt;
- ID: i-0b11803cfd9e623bb
- ID: i-02323c2a2be9759f2
&lt;span class="nv"&gt;$ &lt;/span&gt;aws ec2 terminate-instances &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; i-02323c2a2be9759f2
TerminatingInstances:
- CurrentState:
    Code: 32
    Name: shutting-down
  InstanceId: i-02323c2a2be9759f2
  PreviousState:
    Code: 16
    Name: running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the output when it's considered as UNHEALTHY and replaced with the new instance:&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="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;AutoScalingGroupName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cfn-asg-DhonaWebAppAutoScalingGroup-NQBH0P5D9DNF&lt;/span&gt;
  &lt;span class="na"&gt;AvailabilityZone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3a&lt;/span&gt;
  &lt;span class="na"&gt;HealthStatus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HEALTHY&lt;/span&gt;
  &lt;span class="na"&gt;InstanceId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;i-00c3754aed2929ad9&lt;/span&gt;
  &lt;span class="na"&gt;InstanceType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;t3.small&lt;/span&gt;
  &lt;span class="na"&gt;LaunchTemplate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;LaunchTemplateId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lt-0ab4b34b94589f554&lt;/span&gt;
    &lt;span class="na"&gt;LaunchTemplateName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppLaunchTemplate_6Nl7i61kH5qJ&lt;/span&gt;
    &lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1'&lt;/span&gt;
  &lt;span class="na"&gt;LifecycleState&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;InService&lt;/span&gt;
  &lt;span class="na"&gt;ProtectedFromScaleIn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;AutoScalingGroupName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cfn-asg-DhonaWebAppAutoScalingGroup-NQBH0P5D9DNF&lt;/span&gt;
  &lt;span class="na"&gt;AvailabilityZone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3a&lt;/span&gt;
  &lt;span class="na"&gt;HealthStatus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UNHEALTHY&lt;/span&gt;
  &lt;span class="na"&gt;InstanceId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;i-02323c2a2be9759f2&lt;/span&gt;
  &lt;span class="na"&gt;InstanceType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;t3.nano&lt;/span&gt;
  &lt;span class="na"&gt;LaunchTemplate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;LaunchTemplateId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lt-0ab4b34b94589f554&lt;/span&gt;
    &lt;span class="na"&gt;LaunchTemplateName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppLaunchTemplate_6Nl7i61kH5qJ&lt;/span&gt;
    &lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1'&lt;/span&gt;
  &lt;span class="na"&gt;LifecycleState&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Terminating&lt;/span&gt;
  &lt;span class="na"&gt;ProtectedFromScaleIn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The instance type is t3.small based on the best match with the maximum spot price from the priority.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fuhwskj6mwn0plxeo20s0.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhwskj6mwn0plxeo20s0.png" alt="ASG 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fu0vh1c80p97nnhs0c9w5.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu0vh1c80p97nnhs0c9w5.png" alt="Output 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But what if we terminate the on-demand instance? Will the instance type be changed? The answer is No because the maximum spot price doesn't affect the on-demand setting.&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;aws ec2 terminate-instances &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; i-004b63ceec33e2bb5
TerminatingInstances:
- CurrentState:
    Code: 32
    Name: shutting-down
  InstanceId: i-004b63ceec33e2bb5
  PreviousState:
    Code: 16
    Name: running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2Ffop77a1g79wwjlokwxoj.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffop77a1g79wwjlokwxoj.png" alt="ASG 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6xoiu2nqw9ynajct3siv.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xoiu2nqw9ynajct3siv.png" alt="Output 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Change The On-Demand Allocation Strategy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By changing it to the &lt;code&gt;lowest-price&lt;/code&gt;, it will ignore the priority and choose the lowest price of all available instance types. In this case, it's &lt;code&gt;t3.nano&lt;/code&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;diff cfn-asg-2.yaml cfn-asg-3.yaml
142c142
&amp;lt;           OnDemandAllocationStrategy: prioritized
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;           OnDemandAllocationStrategy: lowest-price
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the stack:&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;aws cloudformation update-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; cfn-asg &lt;span class="nt"&gt;--template-body&lt;/span&gt; file://cfn-asg-3.yaml
StackId: arn:aws:cloudformation:ap-southeast-3:0123456789:stack/cfn-asg/438781a0-1e7e-11ed-b1ba-06ff26b14cdc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terminate the on-demand instance:&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;aws ec2 terminate-instances &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; i-018469de2746c9432
TerminatingInstances:
- CurrentState:
    Code: 32
    Name: shutting-down
  InstanceId: i-018469de2746c9432
  PreviousState:
    Code: 16
    Name: running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we expected, the new on-demand instance type is &lt;code&gt;t3.nano&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="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;AutoScalingGroupName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cfn-asg-DhonaWebAppAutoScalingGroup-NQBH0P5D9DNF&lt;/span&gt;
  &lt;span class="na"&gt;AvailabilityZone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-southeast-3b&lt;/span&gt;
  &lt;span class="na"&gt;HealthStatus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HEALTHY&lt;/span&gt;
  &lt;span class="na"&gt;InstanceId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;i-0f3ab2d7fa671a597&lt;/span&gt;
  &lt;span class="na"&gt;InstanceType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;t3.nano&lt;/span&gt;
  &lt;span class="na"&gt;LaunchTemplate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;LaunchTemplateId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lt-0ab4b34b94589f554&lt;/span&gt;
    &lt;span class="na"&gt;LaunchTemplateName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppLaunchTemplate_6Nl7i61kH5qJ&lt;/span&gt;
    &lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1'&lt;/span&gt;
  &lt;span class="na"&gt;LifecycleState&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;InService&lt;/span&gt;
  &lt;span class="na"&gt;ProtectedFromScaleIn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2Ffx2h0obrsvlbd7zly46i.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx2h0obrsvlbd7zly46i.png" alt="Output 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Make a Change To Launch Template (Create Version)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We have set to use the latest version of the launch template when there is a change, right? So now we will try to prove it.&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;LaunchTemplate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;LaunchTemplateSpecification&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;LaunchTemplateId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppLaunchTemplate&lt;/span&gt;
            &lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;Fn::GetAtt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DhonaWebAppLaunchTemplate&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;LatestVersionNumber&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;diff cfn-asg-3.yaml cfn-asg-4.yaml
193c193,195
&amp;lt;             I&lt;span class="s1"&gt;'m on Availability Zone $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)" &amp;gt; /var/www/html/index.html
---
&amp;gt;             I'&lt;/span&gt;m on Availability Zone &lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://169.254.169.254/latest/meta-data/placement/availability-zone&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;             This is additional line &lt;span class="k"&gt;for &lt;/span&gt;updating launch template&lt;span class="s2"&gt;" &amp;gt; /var/www/html/index.html
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the stack:&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;aws cloudformation update-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; cfn-asg &lt;span class="nt"&gt;--template-body&lt;/span&gt; file://cfn-asg-4.yaml
StackId: arn:aws:cloudformation:ap-southeast-3:0123456789:stack/cfn-asg/438781a0-1e7e-11ed-b1ba-06ff26b14cdc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, let's terminate one spot instance again!&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;aws ec2 describe-spot-instance-requests &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;state,Values&lt;span class="o"&gt;=&lt;/span&gt;active &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"SpotInstanceRequests[*].{ID:InstanceId}"&lt;/span&gt;
- ID: i-00c3754aed2929ad9
- ID: i-0b11803cfd9e623bb
&lt;span class="nv"&gt;$ &lt;/span&gt;aws ec2 terminate-instances &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; i-0b11803cfd9e623bb
TerminatingInstances:
- CurrentState:
    Code: 32
    Name: shutting-down
  InstanceId: i-0b11803cfd9e623bb
  PreviousState:
    Code: 16
    Name: running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're still using the same Auto Scaling Group with the right capacity but in a different version of the launch template. In this case, it's the latest. So that's why we are suggested to use a launch template instead of a launch configuration. By using a launch configuration, we have to create a new one when we need to make a change.&lt;/p&gt;

&lt;p&gt;Now, the latest architecture is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fow6ccg1l650fqyyfygub.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fow6ccg1l650fqyyfygub.png" alt="ASG 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the output!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fmq6yvo2d97dym3mnxgv3.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmq6yvo2d97dym3mnxgv3.png" alt="Output 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright! Those are all the changes we have made to the architecture. Please note that all the changes will be applied to the new instances, not to the current running instances. So for example when one instance is interrupted, the changes will be applied to the new instance created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleanup
&lt;/h2&gt;

&lt;p&gt;If you already followed all the instructions above, you can remove all of them only by deleting the stack. That's why we use CloudFormation, just to make it simple :)&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;aws cloudformation delete-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; cfn-asg
&lt;span class="nv"&gt;$ &lt;/span&gt;aws autoscaling describe-auto-scaling-groups
AutoScalingGroups: &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;aws ec2 describe-spot-instance-requests &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;state,Values&lt;span class="o"&gt;=&lt;/span&gt;active
SpotInstanceRequests: &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;aws ec2 describe-instances &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;instance-state-name,Values&lt;span class="o"&gt;=&lt;/span&gt;running
Reservations: &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;aws cloudformation describe-stacks &lt;span class="nt"&gt;--stack-name&lt;/span&gt; cfn-asg

An error occurred &lt;span class="o"&gt;(&lt;/span&gt;ValidationError&lt;span class="o"&gt;)&lt;/span&gt; when calling the DescribeStacks operation: Stack with &lt;span class="nb"&gt;id &lt;/span&gt;cfn-asg does not exist
&lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this post, I just show you some features that you can use with Auto Scaling. This is not the all features Auto Scaling has. You can mix it with Reserved Instance, use dynamic scaling, and many more. Here I'm not doing it all because this is just a "personal" demo, I don't need too big resources for very high workloads or long-term subscriptions.&lt;/p&gt;

&lt;p&gt;That's it for now! Thank you for coming and I'm looking forward to your feedback. Follow me to get notified when my new post is published!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>autoscaling</category>
      <category>loadbalancer</category>
      <category>cloud</category>
    </item>
    <item>
      <title>2 Easy Steps to Host WordPress Like a Magic Using Amazon Lightsail</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Wed, 20 Jul 2022 05:04:55 +0000</pubDate>
      <link>https://dev.to/aws-builders/2-easy-steps-to-host-wordpress-like-a-magic-on-aws-with-amazon-lightsail-23e2</link>
      <guid>https://dev.to/aws-builders/2-easy-steps-to-host-wordpress-like-a-magic-on-aws-with-amazon-lightsail-23e2</guid>
      <description>&lt;p&gt;Amazon Lightsail is the easiest way to help us get started with AWS very quickly for many purposes such as building websites and many more. There are a lot of services that can be launched with Lightsail very quickly with low and predictable monthly prices. It can be an instance (VPS), storage, container, managed database, and so on. For more information about Amazon Lightsail, click &lt;a href="https://docs.aws.amazon.com/lightsail/"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ScnrvYyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/794sjtkere9bcpd7lg4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ScnrvYyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/794sjtkere9bcpd7lg4j.png" alt="Lightsail WordPress" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, here we will only do 2 things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Import Key Pair&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Please note that the key pair defined in Lightsail is different or not associated with other AWS services like EC2 or IAM User (for CodeCommit).&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;aws lightsail import-key-pair &lt;span class="nt"&gt;--key-pair-name&lt;/span&gt; bitnami &lt;span class="nt"&gt;--public-key-base64&lt;/span&gt; &lt;span class="s2"&gt;"ssh-rsa pubkey-goes-here"&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"operation"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;: &lt;span class="s2"&gt;"4568c408-0349-4788-a922-e9fa6c3591a7"&lt;/span&gt;,
        &lt;span class="s2"&gt;"resourceName"&lt;/span&gt;: &lt;span class="s2"&gt;"bitnami"&lt;/span&gt;,
        &lt;span class="s2"&gt;"resourceType"&lt;/span&gt;: &lt;span class="s2"&gt;"KeyPair"&lt;/span&gt;,
        &lt;span class="s2"&gt;"createdAt"&lt;/span&gt;: 1653553305.861,
        &lt;span class="s2"&gt;"location"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"availabilityZone"&lt;/span&gt;: &lt;span class="s2"&gt;"all"&lt;/span&gt;,
            &lt;span class="s2"&gt;"regionName"&lt;/span&gt;: &lt;span class="s2"&gt;"ap-southeast-1"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="s2"&gt;"isTerminal"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
        &lt;span class="s2"&gt;"operationType"&lt;/span&gt;: &lt;span class="s2"&gt;"ImportKeyPair"&lt;/span&gt;,
        &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"Succeeded"&lt;/span&gt;,
        &lt;span class="s2"&gt;"statusChangedAt"&lt;/span&gt;: 1653553306.012
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create Instance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we create an instance, there are some parameters that we need to define. Those are BluePrint ID and Bundle ID. If you still don't know, you can get the list with the following commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BluePrint ID details for WordPress:
&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;aws lightsail get-blueprints &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1 &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'blueprints[?contains(blueprintId, `wordpress`) == `true`]'&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"blueprintId"&lt;/span&gt;: &lt;span class="s2"&gt;"wordpress"&lt;/span&gt;,
        &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"WordPress"&lt;/span&gt;,
        &lt;span class="s2"&gt;"group"&lt;/span&gt;: &lt;span class="s2"&gt;"wordpress"&lt;/span&gt;,
        &lt;span class="s2"&gt;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"app"&lt;/span&gt;,
        &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Bitnami, the leaders in application packaging, and Automattic, the experts behind WordPress, have teamed up to offer this official WordPress image. This image is a pre-configured, ready-to-run image for running WordPress on Amazon Lightsail. WordPress is the world's most popular content management platform. Whether it's for an enterprise or small business website, or a personal or corporate blog, content authors can easily create content using its new Gutenberg editor, and developers can extend the base platform with additional features. Popular plugins like Jetpack, Akismet, All in One SEO Pack, WP Mail, Google Analytics for WordPress, and Amazon Polly are all pre-installed in this image. Let's Encrypt SSL certificates are supported through an auto-configuration script."&lt;/span&gt;,
        &lt;span class="s2"&gt;"isActive"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
        &lt;span class="s2"&gt;"minPower"&lt;/span&gt;: 0,
        &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"5.9.3-8"&lt;/span&gt;,
        &lt;span class="s2"&gt;"versionCode"&lt;/span&gt;: &lt;span class="s2"&gt;"1"&lt;/span&gt;,
        &lt;span class="s2"&gt;"productUrl"&lt;/span&gt;: &lt;span class="s2"&gt;"https://aws.amazon.com/marketplace/pp/B00NN8Y43U"&lt;/span&gt;,
        &lt;span class="s2"&gt;"licenseUrl"&lt;/span&gt;: &lt;span class="s2"&gt;"https://d7umqicpi7263.cloudfront.net/eula/product/7d426cb7-9522-4dd7-a56b-55dd8cc1c8d0/588fd495-6492-4610-b3e8-d15ce864454c.txt"&lt;/span&gt;,
        &lt;span class="s2"&gt;"platform"&lt;/span&gt;: &lt;span class="s2"&gt;"LINUX_UNIX"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"blueprintId"&lt;/span&gt;: &lt;span class="s2"&gt;"wordpress_multisite"&lt;/span&gt;,
        &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"WordPress Multisite"&lt;/span&gt;,
        &lt;span class="s2"&gt;"group"&lt;/span&gt;: &lt;span class="s2"&gt;"wordpress_multisite"&lt;/span&gt;,
        &lt;span class="s2"&gt;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"app"&lt;/span&gt;,
        &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"WordPress Multisite is ideal for organizations such as universities, corporations, and agencies that need to enable many people to host and manage their own websites while giving overall control to a central administrator. These websites can all have unique domain names and layouts while sharing assets such as themes and plugins. Popular plugins like Jetpack, Akismet, All in One SEO Pack, WP Mail, Google Analytics for WordPress, and Amazon Polly are all pre-installed in this image. Let's Encrypt SSL certificates are supported through an auto-configuration script. This image is certified by Bitnami as secure, up-to-date, and packaged using industry best practices."&lt;/span&gt;,
        &lt;span class="s2"&gt;"isActive"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
        &lt;span class="s2"&gt;"minPower"&lt;/span&gt;: 0,
        &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"5.9.3-8"&lt;/span&gt;,
        &lt;span class="s2"&gt;"versionCode"&lt;/span&gt;: &lt;span class="s2"&gt;"1"&lt;/span&gt;,
        &lt;span class="s2"&gt;"productUrl"&lt;/span&gt;: &lt;span class="s2"&gt;"https://aws.amazon.com/marketplace/pp/B00NN8XE6S"&lt;/span&gt;,
        &lt;span class="s2"&gt;"licenseUrl"&lt;/span&gt;: &lt;span class="s2"&gt;"https://d7umqicpi7263.cloudfront.net/eula/product/2f1d4d67-324b-41d7-8af9-b7860d269c6d/6338ef47-28a8-482d-b57a-4859280a021e.txt"&lt;/span&gt;,
        &lt;span class="s2"&gt;"platform"&lt;/span&gt;: &lt;span class="s2"&gt;"LINUX_UNIX"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Bundle ID for the cheapest one ($3.5 for nano 2.0):
&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;aws lightsail get-bundles &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'bundles[0]'&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"price"&lt;/span&gt;: 3.5,
    &lt;span class="s2"&gt;"cpuCount"&lt;/span&gt;: 1,
    &lt;span class="s2"&gt;"diskSizeInGb"&lt;/span&gt;: 20,
    &lt;span class="s2"&gt;"bundleId"&lt;/span&gt;: &lt;span class="s2"&gt;"nano_2_0"&lt;/span&gt;,
    &lt;span class="s2"&gt;"instanceType"&lt;/span&gt;: &lt;span class="s2"&gt;"nano"&lt;/span&gt;,
    &lt;span class="s2"&gt;"isActive"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Nano"&lt;/span&gt;,
    &lt;span class="s2"&gt;"power"&lt;/span&gt;: 300,
    &lt;span class="s2"&gt;"ramSizeInGb"&lt;/span&gt;: 0.5,
    &lt;span class="s2"&gt;"transferPerMonthInGb"&lt;/span&gt;: 1024,
    &lt;span class="s2"&gt;"supportedPlatforms"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"LINUX_UNIX"&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's create the instance!&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;aws lightsail create-instances &lt;span class="nt"&gt;--instance-names&lt;/span&gt; wp-instance &lt;span class="nt"&gt;--availability-zone&lt;/span&gt; ap-southeast-1a &lt;span class="nt"&gt;--blueprint-id&lt;/span&gt; wordpress &lt;span class="nt"&gt;--bundle-id&lt;/span&gt; nano_2_0 &lt;span class="nt"&gt;--key-pair-name&lt;/span&gt; bitnami &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"operations"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;: &lt;span class="s2"&gt;"b4324f47-a520-4424-b99c-ad026c50546b"&lt;/span&gt;,
            &lt;span class="s2"&gt;"resourceName"&lt;/span&gt;: &lt;span class="s2"&gt;"wp-instance"&lt;/span&gt;,
            &lt;span class="s2"&gt;"resourceType"&lt;/span&gt;: &lt;span class="s2"&gt;"Instance"&lt;/span&gt;,
            &lt;span class="s2"&gt;"createdAt"&lt;/span&gt;: 1653555007.628,
            &lt;span class="s2"&gt;"location"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"availabilityZone"&lt;/span&gt;: &lt;span class="s2"&gt;"ap-southeast-1a"&lt;/span&gt;,
                &lt;span class="s2"&gt;"regionName"&lt;/span&gt;: &lt;span class="s2"&gt;"ap-southeast-1"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;,
            &lt;span class="s2"&gt;"isTerminal"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;,
            &lt;span class="s2"&gt;"operationType"&lt;/span&gt;: &lt;span class="s2"&gt;"CreateInstance"&lt;/span&gt;,
            &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"Started"&lt;/span&gt;,
            &lt;span class="s2"&gt;"statusChangedAt"&lt;/span&gt;: 1653555007.628
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;aws lightsail get-instances &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1 &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'instances[].[name, location, blueprintId, bundleId, privateIpAddress, publicIpAddress]'&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"wp-instance"&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"availabilityZone"&lt;/span&gt;: &lt;span class="s2"&gt;"ap-southeast-1a"&lt;/span&gt;,
            &lt;span class="s2"&gt;"regionName"&lt;/span&gt;: &lt;span class="s2"&gt;"ap-southeast-1"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="s2"&gt;"wordpress"&lt;/span&gt;,
        &lt;span class="s2"&gt;"nano_2_0"&lt;/span&gt;,
        &lt;span class="s2"&gt;"172.26.13.11"&lt;/span&gt;,
        &lt;span class="s2"&gt;"18.141.24.138"&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's access it through SSH and web browser!&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;ssh bitnami@18.141.24.138
The programs included with the Debian GNU/Linux system are free software&lt;span class="p"&gt;;&lt;/span&gt;
the exact distribution terms &lt;span class="k"&gt;for &lt;/span&gt;each program are described &lt;span class="k"&gt;in &lt;/span&gt;the
individual files &lt;span class="k"&gt;in&lt;/span&gt; /usr/share/doc/&lt;span class="k"&gt;*&lt;/span&gt;/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
       ___ _ _                   _
      | _ |_&lt;span class="o"&gt;)&lt;/span&gt; |_ _ _  __ _ _ __ &lt;span class="o"&gt;(&lt;/span&gt;_&lt;span class="o"&gt;)&lt;/span&gt;
      | _ &lt;span class="se"&gt;\ &lt;/span&gt;|  _| &lt;span class="s1"&gt;' \/ _` | '&lt;/span&gt;  &lt;span class="se"&gt;\|&lt;/span&gt; |
      |___/_|&lt;span class="se"&gt;\_&lt;/span&gt;_|_|_|&lt;span class="se"&gt;\_&lt;/span&gt;_,_|_|_|_|_|

  &lt;span class="k"&gt;***&lt;/span&gt; Welcome to the WordPress packaged by Bitnami 5.9.3-8         &lt;span class="k"&gt;***&lt;/span&gt;
  &lt;span class="k"&gt;***&lt;/span&gt; Documentation:  https://docs.bitnami.com/aws/apps/wordpress/ &lt;span class="k"&gt;***&lt;/span&gt;
  &lt;span class="k"&gt;***&lt;/span&gt;                 https://docs.bitnami.com/aws/                &lt;span class="k"&gt;***&lt;/span&gt;
  &lt;span class="k"&gt;***&lt;/span&gt; Bitnami Forums: https://community.bitnami.com/               &lt;span class="k"&gt;***&lt;/span&gt;
bitnami@ip-172-26-13-11:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;bitnami_application_password 
KPInbPj1giRB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because we have the password now and the default username is user, let's go through dashboard!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PQU-289w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vszygsr0ji6xs837ubrz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PQU-289w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vszygsr0ji6xs837ubrz.png" alt="WordPress" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lm9PFhHn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9x74vi34otxu6z4n0uy0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lm9PFhHn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9x74vi34otxu6z4n0uy0.png" alt="WordPress Login" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wMm8rpSG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9plh97gv0oqusd4pzbuc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wMm8rpSG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9plh97gv0oqusd4pzbuc.png" alt="WordPress Dashboard" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a wrap! In case you want to delete them, just run delete command &lt;code&gt;delete-instance&lt;/code&gt; &amp;amp; &lt;code&gt;delete-key-pair&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;That's it! Thank you for coming and I'm looking forward to your feedback. Follow me to get notified when my new post is published!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>wordpress</category>
      <category>lightsail</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Best Way for Giving Permission to AWS Services</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Wed, 20 Jul 2022 04:57:39 +0000</pubDate>
      <link>https://dev.to/aws-builders/best-way-for-giving-permission-to-aws-services-286m</link>
      <guid>https://dev.to/aws-builders/best-way-for-giving-permission-to-aws-services-286m</guid>
      <description>&lt;p&gt;For AWS IAM service, we must keep at least privileged access. It's the best practice in using IAM for security purposes. For IAM user, attaching policy at a group level is the best practice. For "specific" AWS services, IAM role is the best way to give permission for the source and IAM policy for the destination.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Use IAM role to give permission for EC2 instances, let's say for accessing S3 such as listing or creating a bucket.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use IAM policy to only allow access from any sources, let's say for static website purposes we allow public access to specific buckets.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here I'll you the first option which is IAM role!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create EC2 instance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here I'll create an EC2 instance through CLI with Amazon Linux 2 as AMI and leave the rest to use default as it is. Before that, I'll also import the key pair.&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;aws ec2 import-key-pair &lt;span class="nt"&gt;--key-name&lt;/span&gt; &lt;span class="s2"&gt;"ec2-user"&lt;/span&gt; &lt;span class="nt"&gt;--public-key-material&lt;/span&gt; fileb://home/nurulramadhona/.ssh/id_rsa.pub
&lt;span class="nv"&gt;$ &lt;/span&gt;aws ec2 run-instances &lt;span class="nt"&gt;--image-id&lt;/span&gt; ami-021fb2b73ff1efc96 &lt;span class="nt"&gt;--count&lt;/span&gt; 1 &lt;span class="nt"&gt;--instance-type&lt;/span&gt; t3.micro &lt;span class="nt"&gt;--key-name&lt;/span&gt; ec2-user
&lt;span class="nv"&gt;$ &lt;/span&gt;aws ec2 describe-instances &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Reservations[].Instances[].{PublicIP:PublicIpAddress, ID:InstanceId}'&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"PublicIP"&lt;/span&gt;: &lt;span class="s2"&gt;"108.136.45.150"&lt;/span&gt;,
        &lt;span class="s2"&gt;"ID"&lt;/span&gt;: &lt;span class="s2"&gt;"i-0f3df2b1eb51bc6a1"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create IAM role &amp;amp; attach policy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Trust document:&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;cat &lt;/span&gt;ec2-role.json 
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Service"&lt;/span&gt;: &lt;span class="s2"&gt;"ec2.amazonaws.com"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;aws iam create-role &lt;span class="nt"&gt;--role-name&lt;/span&gt; ec2-role &lt;span class="nt"&gt;--assume-role-policy-document&lt;/span&gt; file://ec2-role.json
&lt;span class="nv"&gt;$ &lt;/span&gt;aws iam attach-role-policy &lt;span class="nt"&gt;--role-name&lt;/span&gt; ec2-role &lt;span class="nt"&gt;--policy-arn&lt;/span&gt; arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Create instance profile &amp;amp; add role&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An instance profile is a container for an IAM role that you can use to pass role information to an EC2 instance when the instance starts. Please note that we only can have one role per instance profile.&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;aws iam create-instance-profile &lt;span class="nt"&gt;--instance-profile-name&lt;/span&gt; ec2-profile
&lt;span class="nv"&gt;$ &lt;/span&gt;aws iam add-role-to-instance-profile &lt;span class="nt"&gt;--role-name&lt;/span&gt; ec2-role &lt;span class="nt"&gt;--instance-profile-name&lt;/span&gt; ec2-profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Associate instance profile to EC2 instances&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 associate-iam-instance-profile &lt;span class="nt"&gt;--instance-id&lt;/span&gt; i-0f3df2b1eb51bc6a1 &lt;span class="nt"&gt;--iam-instance-profile&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ec2-profile
aws ec2 describe-iam-instance-profile-associations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's check! Before:&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;ssh ec2-user@108.136.45.150 

       __|  __|_  &lt;span class="o"&gt;)&lt;/span&gt;
       _|  &lt;span class="o"&gt;(&lt;/span&gt;     /   Amazon Linux 2 AMI
      ___|&lt;span class="se"&gt;\_&lt;/span&gt;__|___|

https://aws.amazon.com/amazon-linux-2/
4 package&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; needed &lt;span class="k"&gt;for &lt;/span&gt;security, out of 5 available
Run &lt;span class="s2"&gt;"sudo yum update"&lt;/span&gt; to apply all updates.
&lt;span class="o"&gt;[&lt;/span&gt;ec2-user@ip-172-31-0-125 ~]&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3 &lt;span class="nb"&gt;ls
&lt;/span&gt;Unable to locate credentials. You can configure credentials by running &lt;span class="s2"&gt;"aws configure"&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After:&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;[&lt;/span&gt;ec2-user@ip-172-31-0-125 ~]&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3 &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;ec2-user@ip-172-31-0-125 ~]&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3 mb s3://bucket-ec2-role
make_bucket failed: s3://bucket-ec2-role An error occurred &lt;span class="o"&gt;(&lt;/span&gt;AccessDenied&lt;span class="o"&gt;)&lt;/span&gt; when calling the CreateBucket operation: Access Denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Least Privilege Access&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As we can see above, we can list a bucket (currently empty) but can't create a bucket with an error &lt;code&gt;Access Denied&lt;/code&gt;. If we really need it, we can attach one more policy to the IAM role. This is what I mean by giving permission as needed. So, let's try!&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;aws iam attach-role-policy &lt;span class="nt"&gt;--role-name&lt;/span&gt; ec2-role &lt;span class="nt"&gt;--policy-arn&lt;/span&gt; arn:aws:iam::aws:policy/AmazonS3FullAccess
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;ec2-user@ip-172-31-0-125 ~]&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3 mb s3://bucket-ec2-role
make_bucket: bucket-ec2-role
&lt;span class="o"&gt;[&lt;/span&gt;ec2-user@ip-172-31-0-125 ~]&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3 &lt;span class="nb"&gt;ls
&lt;/span&gt;2022-05-26 02:43:47 bucket-ec2-role
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we also can detach if the policy is no longer needed.&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;aws iam detach-role-policy &lt;span class="nt"&gt;--role-name&lt;/span&gt; ec2-role &lt;span class="nt"&gt;--policy-arn&lt;/span&gt; arn:aws:iam::aws:policy/AmazonS3FullAccess
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;ec2-user@ip-172-31-0-125 ~]&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3 mb s3://bucket-ec2-role2
make_bucket failed: s3://bucket-ec2-role2 An error occurred &lt;span class="o"&gt;(&lt;/span&gt;AccessDenied&lt;span class="o"&gt;)&lt;/span&gt; when calling the CreateBucket operation: Access Denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Additional:&lt;/strong&gt; In case you want to delete the IAM role, make sure we have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Remove the role from the instance profile before deleting the instance profile.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete instance profile.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detach all policies from the role.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! Thank you for coming and I'm looking forward to your feedback. Follow me to get notified when my new post is published!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ec2</category>
      <category>s3</category>
      <category>iam</category>
    </item>
    <item>
      <title>GitHub Vibes on AWS: What Makes CodeCommit Special?</title>
      <dc:creator>Nurul Ramadhona</dc:creator>
      <pubDate>Sat, 16 Jul 2022 05:55:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/github-vibes-on-aws-what-makes-codecommit-special-1ak5</link>
      <guid>https://dev.to/aws-builders/github-vibes-on-aws-what-makes-codecommit-special-1ak5</guid>
      <description>&lt;p&gt;AWS CodeCommit is a secure, highly scalable, managed source control service that hosts private Git repositories. Simply means we can use GitHub on AWS with any special features such as easy scale and many more. One of the biggest benefits is it can be integrated with other AWS services. Before we talk about it, let me show you how to set up or use it first.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Use CodeCommit&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Setup Credential&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just like we use GitHub, we need to set up credentials to be able to access our repositories but in this case, we will integrate it using IAM either HTTPS or SSH. Here I'll use SSH by uploading my public key to one of my IAM User credentials.&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;aws iam upload-ssh-public-key &lt;span class="nt"&gt;--user-name&lt;/span&gt; dhona &lt;span class="nt"&gt;--ssh-public-key-body&lt;/span&gt; file:///home/nurulramadhona/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;config&lt;/code&gt; file under &lt;code&gt;.ssh&lt;/code&gt; directory:&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;chmod &lt;/span&gt;600 .ssh/config
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .ssh/config 
Host git-codecommit.&lt;span class="k"&gt;*&lt;/span&gt;.amazonaws.com
  User &lt;span class="o"&gt;(&lt;/span&gt;ssh-key-id-goes-here&lt;span class="o"&gt;)&lt;/span&gt;
  IdentityFile /home/nurulramadhona/.ssh/id_rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create &amp;amp; Clone Repository&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Please specify the "other" region if it's not available yet in your region.&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;aws codecommit create-repository &lt;span class="nt"&gt;--repository-name&lt;/span&gt; ops-io &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="nv"&gt;$ &lt;/span&gt;git clone ssh://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/ops-io
Cloning into &lt;span class="s1"&gt;'ops-io'&lt;/span&gt;...
warning: You appear to have cloned an empty repository.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Make Any Changes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub commands:
&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;cd &lt;/span&gt;ops-io/
~/ops-io&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;test.txt
this is first file
~/ops-io&lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="nt"&gt;-A&lt;/span&gt;
~/ops-io&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"upload first file"&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;master &lt;span class="o"&gt;(&lt;/span&gt;root-commit&lt;span class="o"&gt;)&lt;/span&gt; 1406bd0] upload first file
 1 file changed, 1 insertion&lt;span class="o"&gt;(&lt;/span&gt;+&lt;span class="o"&gt;)&lt;/span&gt;
 create mode 100644 test.txt
~/ops-io&lt;span class="nv"&gt;$ &lt;/span&gt;git push origin master
Enumerating objects: 3, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Counting objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;3/3&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Writing objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;3/3&lt;span class="o"&gt;)&lt;/span&gt;, 236 bytes | 236.00 KiB/s, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Total 3 &lt;span class="o"&gt;(&lt;/span&gt;delta 0&lt;span class="o"&gt;)&lt;/span&gt;, reused 0 &lt;span class="o"&gt;(&lt;/span&gt;delta 0&lt;span class="o"&gt;)&lt;/span&gt;
To ssh://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/ops-io
 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;new branch]      master -&amp;gt; master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;CodeCommit commands:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/ops-io&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"this is second file"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; file.txt
~/ops-io&lt;span class="nv"&gt;$ &lt;/span&gt;aws codecommit get-branch &lt;span class="nt"&gt;--repository-name&lt;/span&gt; ops-io &lt;span class="nt"&gt;--branch-name&lt;/span&gt; master &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"branch"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"branchName"&lt;/span&gt;: &lt;span class="s2"&gt;"master"&lt;/span&gt;,
        &lt;span class="s2"&gt;"commitId"&lt;/span&gt;: &lt;span class="s2"&gt;"1406bd0566858448e486011edc364ca3a77d0b0d"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
~/ops-io&lt;span class="nv"&gt;$ &lt;/span&gt;aws codecommit create-commit &lt;span class="nt"&gt;--repository-name&lt;/span&gt; ops-io &lt;span class="nt"&gt;--branch-name&lt;/span&gt; master &lt;span class="nt"&gt;--parent-commit-id&lt;/span&gt; 1406bd0566858448e486011edc364ca3a77d0b0d &lt;span class="nt"&gt;--put-files&lt;/span&gt; &lt;span class="s2"&gt;"filePath=file.txt,fileContent='upload 2nd file'"&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"commitId"&lt;/span&gt;: &lt;span class="s2"&gt;"307e9fb75d0a7ccc490aacbf28aba957342a8c3b"&lt;/span&gt;,
    &lt;span class="s2"&gt;"treeId"&lt;/span&gt;: &lt;span class="s2"&gt;"918e7c9702c916bc7b67f7645432e048cdfe94a4"&lt;/span&gt;,
    &lt;span class="s2"&gt;"filesAdded"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"absolutePath"&lt;/span&gt;: &lt;span class="s2"&gt;"file.txt"&lt;/span&gt;,
            &lt;span class="s2"&gt;"blobId"&lt;/span&gt;: &lt;span class="s2"&gt;"6e29f4102c6b829414b53053cd65c1b123d28d29"&lt;/span&gt;,
            &lt;span class="s2"&gt;"fileMode"&lt;/span&gt;: &lt;span class="s2"&gt;"NORMAL"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="s2"&gt;"filesUpdated"&lt;/span&gt;: &lt;span class="o"&gt;[]&lt;/span&gt;,
    &lt;span class="s2"&gt;"filesDeleted"&lt;/span&gt;: &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. List Repositories &amp;amp; Branches&lt;/strong&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;aws codecommit get-branch &lt;span class="nt"&gt;--repository-name&lt;/span&gt; ops-io &lt;span class="nt"&gt;--branch-name&lt;/span&gt; master &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"branch"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"branchName"&lt;/span&gt;: &lt;span class="s2"&gt;"master"&lt;/span&gt;,
        &lt;span class="s2"&gt;"commitId"&lt;/span&gt;: &lt;span class="s2"&gt;"1406bd0566858448e486011edc364ca3a77d0b0d"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;aws codecommit get-folder &lt;span class="nt"&gt;--repository-name&lt;/span&gt; ops-io &lt;span class="nt"&gt;--folder-path&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"commitId"&lt;/span&gt;: &lt;span class="s2"&gt;"307e9fb75d0a7ccc490aacbf28aba957342a8c3b"&lt;/span&gt;,
    &lt;span class="s2"&gt;"folderPath"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
    &lt;span class="s2"&gt;"treeId"&lt;/span&gt;: &lt;span class="s2"&gt;"918e7c9702c916bc7b67f7645432e048cdfe94a4"&lt;/span&gt;,
    &lt;span class="s2"&gt;"subFolders"&lt;/span&gt;: &lt;span class="o"&gt;[]&lt;/span&gt;,
    &lt;span class="s2"&gt;"files"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"blobId"&lt;/span&gt;: &lt;span class="s2"&gt;"6e29f4102c6b829414b53053cd65c1b123d28d29"&lt;/span&gt;,
            &lt;span class="s2"&gt;"absolutePath"&lt;/span&gt;: &lt;span class="s2"&gt;"file.txt"&lt;/span&gt;,
            &lt;span class="s2"&gt;"relativePath"&lt;/span&gt;: &lt;span class="s2"&gt;"file.txt"&lt;/span&gt;,
            &lt;span class="s2"&gt;"fileMode"&lt;/span&gt;: &lt;span class="s2"&gt;"NORMAL"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"blobId"&lt;/span&gt;: &lt;span class="s2"&gt;"ce553855c343e93616e1e937cd288a9824f0d761"&lt;/span&gt;,
            &lt;span class="s2"&gt;"absolutePath"&lt;/span&gt;: &lt;span class="s2"&gt;"test.txt"&lt;/span&gt;,
            &lt;span class="s2"&gt;"relativePath"&lt;/span&gt;: &lt;span class="s2"&gt;"test.txt"&lt;/span&gt;,
            &lt;span class="s2"&gt;"fileMode"&lt;/span&gt;: &lt;span class="s2"&gt;"NORMAL"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="s2"&gt;"symbolicLinks"&lt;/span&gt;: &lt;span class="o"&gt;[]&lt;/span&gt;,
    &lt;span class="s2"&gt;"subModules"&lt;/span&gt;: &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Special Task: Copy S3 Object To CodeCommit&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As I mentioned before, one of the biggest benefits we host services on AWS is that they can be integrated with one another. Here I'll give you a simple task of how we can do it.&lt;/p&gt;

&lt;p&gt;I'll go with CloudFormation to create a new repository named S3 and copy objects (zip format) from the S3 bucket to the branch bucket.&lt;/p&gt;

&lt;p&gt;Before that, I'll create a new bucket named repository-ops-io with versioning enabled and upload the zip file to that bucket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create Bucket&lt;/strong&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;aws s3 mb s3://repository-ops-io &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
make_bucket: repository-ops-io
&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3api put-bucket-versioning &lt;span class="nt"&gt;--bucket&lt;/span&gt; repository-ops-io &lt;span class="nt"&gt;--versioning-configuration&lt;/span&gt; &lt;span class="nv"&gt;MFADelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Disabled,Status&lt;span class="o"&gt;=&lt;/span&gt;Enabled &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3api get-bucket-versioning &lt;span class="nt"&gt;--bucket&lt;/span&gt; repository-ops-io &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"Status"&lt;/span&gt;: &lt;span class="s2"&gt;"Enabled"&lt;/span&gt;,
    &lt;span class="s2"&gt;"MFADelete"&lt;/span&gt;: &lt;span class="s2"&gt;"Disabled"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Upload Object&lt;/strong&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;touch &lt;/span&gt;s3.txt
&lt;span class="nv"&gt;$ &lt;/span&gt;zip s3.zip s3.txt
  adding: s3.txt &lt;span class="o"&gt;(&lt;/span&gt;stored 0%&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls
&lt;/span&gt;s3.zip
&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;s3.zip s3://repository-ops-io &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
upload: ./s3.zip to s3://repository-ops-io/s3.zip
&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3api list-object-versions &lt;span class="nt"&gt;--bucket&lt;/span&gt; repository-ops-io &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Versions[].[Key, VersionId]'&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"s3.zip"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Km7s2m1Jd2FlcvoIi9v7n.KUenzjHZ5R"&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Create Stack&lt;/strong&gt; I give the template name &lt;code&gt;ops-io.yaml&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;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2010-09-09&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;Repository&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="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AWS::CodeCommit::Repository'&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;RepositoryName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;s3&lt;/span&gt;
      &lt;span class="na"&gt;RepositoryDescription&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;S3 to Codecommit&lt;/span&gt;
      &lt;span class="na"&gt;Code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;BranchName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bucket&lt;/span&gt;
        &lt;span class="na"&gt;S3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;repository-ops-io&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;s3.zip&lt;/span&gt;
          &lt;span class="na"&gt;ObjectVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Km7s2m1Jd2FlcvoIi9v7n.KUenzjHZ5R&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;aws cloudformation create-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; ops-io &lt;span class="nt"&gt;--template-body&lt;/span&gt; file://ops-io.yaml &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1 &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"StackId"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:cloudformation:ap-southeast-1:0123456789:stack/ops-io/ae15bb10-dcaf-11ec-b865-0a5e031cf822"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Let's check!&lt;/strong&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;aws codecommit list-repositories &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"repositories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"repositoryName"&lt;/span&gt;: &lt;span class="s2"&gt;"ops-io"&lt;/span&gt;,
            &lt;span class="s2"&gt;"repositoryId"&lt;/span&gt;: &lt;span class="s2"&gt;"706334d5-c480-4b69-9395-512e0aff3a4c"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"repositoryName"&lt;/span&gt;: &lt;span class="s2"&gt;"s3"&lt;/span&gt;,
            &lt;span class="s2"&gt;"repositoryId"&lt;/span&gt;: &lt;span class="s2"&gt;"71719f7e-5e45-4b25-aa82-3247bfd297a3"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;aws codecommit list-branches &lt;span class="nt"&gt;--repository-name&lt;/span&gt; s3 &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"branches"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"bucket"&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;aws codecommit get-folder &lt;span class="nt"&gt;--repository-name&lt;/span&gt; s3 &lt;span class="nt"&gt;--folder-path&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"commitId"&lt;/span&gt;: &lt;span class="s2"&gt;"1c69f63e89e579a7e41b27c2b9a97e2f90344f26"&lt;/span&gt;,
    &lt;span class="s2"&gt;"folderPath"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
    &lt;span class="s2"&gt;"treeId"&lt;/span&gt;: &lt;span class="s2"&gt;"3210de697af8657277ba1d8ec5509438f4521482"&lt;/span&gt;,
    &lt;span class="s2"&gt;"subFolders"&lt;/span&gt;: &lt;span class="o"&gt;[]&lt;/span&gt;,
    &lt;span class="s2"&gt;"files"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"blobId"&lt;/span&gt;: &lt;span class="s2"&gt;"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"&lt;/span&gt;,
            &lt;span class="s2"&gt;"absolutePath"&lt;/span&gt;: &lt;span class="s2"&gt;"s3.txt"&lt;/span&gt;,
            &lt;span class="s2"&gt;"relativePath"&lt;/span&gt;: &lt;span class="s2"&gt;"s3.txt"&lt;/span&gt;,
            &lt;span class="s2"&gt;"fileMode"&lt;/span&gt;: &lt;span class="s2"&gt;"NORMAL"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="s2"&gt;"symbolicLinks"&lt;/span&gt;: &lt;span class="o"&gt;[]&lt;/span&gt;,
    &lt;span class="s2"&gt;"subModules"&lt;/span&gt;: &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Additional:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To delete all resources created above, please do the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Delete the S3 object with the version mentioned&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the S3 bucket&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the CloudFormation stack&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the CodeCommit repository&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! Thank you for coming and I'm looking forward to your feedback. Follow me to get notified when my new post is published!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>versioncontrol</category>
      <category>github</category>
      <category>codecommit</category>
    </item>
  </channel>
</rss>
