<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Dustin Hammond on Medium]]></title>
        <description><![CDATA[Stories by Dustin Hammond on Medium]]></description>
        <link>https://medium.com/@epselon?source=rss-fc573f9ba90a------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*6Pwrccq0lkUu-dJj.jpg</url>
            <title>Stories by Dustin Hammond on Medium</title>
            <link>https://medium.com/@epselon?source=rss-fc573f9ba90a------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 28 May 2026 00:58:02 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@epselon/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Reduce daily distractions to increase productivity (Screen Time)]]></title>
            <link>https://medium.com/@epselon/reduce-daily-distractions-to-increase-productivity-screen-time-d8d186699e67?source=rss-fc573f9ba90a------2</link>
            <guid isPermaLink="false">https://medium.com/p/d8d186699e67</guid>
            <dc:creator><![CDATA[Dustin Hammond]]></dc:creator>
            <pubDate>Thu, 23 Mar 2023 17:12:32 GMT</pubDate>
            <atom:updated>2023-03-23T17:12:32.271Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/344/1*G-Mq0QLImvCkPZ2-Y5zjJg.png" /><figcaption>Applications are “speed bumped” preventing you from accessing without a prompt</figcaption></figure><p>Ever since mobile phone devices became much more than just phones to make calls, they have become an increasing problem as it pertains to self-productivity. In fact, some of these applications are designed to take advantage of our increasingly short attention spans and keep us hooked (i.e: TikTok, Youtube Shorts, etc).</p><p>I came across a built-in feature with Apple iPhone that has me so excited I just had to share.</p><p>Do you find yourself distracted at times during your day? Do you happen to have an addiction to YouTube or other video sites? Do you happen to check up on Facebook or other social media notifications a bit much?</p><p>If you have an iPhone, this solution is for you!</p><h3>Screen Time (how to setup)</h3><p>The “Screen Time” feature is available in your iPhone settings.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/334/1*fRPt03Al993F5ztMXmgTVQ.png" /><figcaption>The “Screen Time” selection is highlighted under “Settings”</figcaption></figure><p>Once you access the “Screen Time” settings page, you can follow these steps to being:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/356/1*ph8ecyAWWgasE_-eJ-S5jg.png" /></figure><p>You’ll be greeted with a page that hosts some metrics that reveal your general screen time activities. At the bottom, you’ll also observe some additional options you can use to restrict Screen Time based on certain conditions.</p><h3>Downtime</h3><p>This is my favorite setting — as it allows you to control availability to your applications on a scheduled basis:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/374/1*_qxlTKMKbiavYThP5XOGaA.png" /><figcaption>The “Downtime” setting with the schedule options highlighted</figcaption></figure><p>As shown above, we can enable “scheduled” to increase our productivty during certain periods of the day.</p><p>As an example, a typical workday consists of a time range across most of our daylight hours on weekdays.</p><ul><li>You can specifically target individual days to have certain schedules</li><li>You can disable the speed bump to access your App’s on targeted days</li></ul><h3>Always Allowed</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/354/1*ZoahhUvqHOYBiG9btpl1mA.png" /><figcaption>The “Always Allowed” settings to override certain Apps from being “speed bumped”</figcaption></figure><p>You can use this setting to specify applications that you don’t want blocked. Think critical needs such as communications, MFA Apps, etc.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/838/1*yxq2HVr13NA5GnydZ4oTtQ.png" /></figure><h3>Closing Thoughts</h3><p>This is just an example of how you could use this feature to help increase your productivity during the day. Some considerations:</p><ul><li>The Apps are only “speed bumped” meaning it prompts you that your “limit” has been reached for App access but allows you to override if you like.</li><li>There are other Apps on the App Store that provide this feature, but I don’t think they are any better than this built-in feature.</li></ul><p>You should try and respect the limits you set as much as possible.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d8d186699e67" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Put and update items in a DynamoDB table using Python]]></title>
            <link>https://medium.com/@epselon/put-and-update-items-in-a-dynamodb-table-using-python-b22c985ab8cb?source=rss-fc573f9ba90a------2</link>
            <guid isPermaLink="false">https://medium.com/p/b22c985ab8cb</guid>
            <dc:creator><![CDATA[Dustin Hammond]]></dc:creator>
            <pubDate>Sat, 04 Mar 2023 22:04:04 GMT</pubDate>
            <atom:updated>2023-03-04T22:04:04.326Z</atom:updated>
            <content:encoded><![CDATA[<h3>Overview</h3><p>This article will briefly discuss how to update an item in a DynamoDB table on AWS.</p><h3>Sample data (dictionary)</h3><p>Here is our sample data based off of an old EBS public snapshot (I have censored the relevant identifiable information):</p><pre>import boto3<br><br>snapshot_details_pull = {<br>    &#39;Description&#39;: &#39;Copied for DestinationAmi ami-00000000000000000 from SourceAmi ami-11111111111111111 for SourceSnapshot snap-aabbccddeeffgghhi. Task created on X.&#39;,<br>    &#39;Encrypted&#39;: False, <br>    &#39;OwnerId&#39;: &#39;999999999999&#39;, <br>    &#39;Progress&#39;: &#39;100%&#39;, <br>    &#39;SnapshotId&#39;: &#39;snap-aabbccddeeffgghhi&#39;, <br>    &#39;StartTime&#39;: datetime.datetime(2017, 1, 01, 00, 00, tzinfo=tzutc()),<br>    &#39;State&#39;: &#39;completed&#39;, <br>    &#39;VolumeId&#39;: &#39;vol-ffffffff&#39;, <br>    &#39;VolumeSize&#39;: 10, <br>    &#39;StorageTier&#39;: &#39;standard&#39; <br>}<br><br># Setup the DynamoDB connection<br>session = boto3.session.Session() #Use the profile_name parameter if needed<br>resource = session.resource(&#39;dynamodb&#39;) #Use resource - not the client here<br>table = resource.Table(&#39;&lt;insert your table name here&#39;) #A table must already exist</pre><h3>Put an item</h3><p>In order to “put” an item into a DynamoDB table, there are a few per-requisites we’ll need to consider as it pertains to the data types of each key/value pair.</p><p>If we attempt to “put” an item now, we will encounter the following error:</p><p><em>TypeError: Unsupported type “&lt;class ‘datetime.datetime’&gt;” for value…</em></p><p>We will need to update the value of the “StartTime” key to an “iso format” using the following snippet in your Python interpreter for a quick conversion:</p><pre>snapshot_details_pull[&#39;StartTime&#39;] = snapshot_details_pull[&#39;StartTime&#39;].isoformat()</pre><p>Next, this dictionary does not have the “partition key” resident in its key/value pairs. In this case, consider the “parition key” of this DynamoDB to be a key pair value of “id” followed by an a string value that should be unique.</p><p>In DynamoDB terminology, there are a few considerations to take in as far as the value type identifiers are concerned.</p><p>S = string<br>N= integer<br>B=bytes<br>SS=list<br>NS=number set (list)<br>BS=binary set (list)<br>M=map (dictionary)<br>L= “attribute list” (dictionary of a list of dictionaries)<br>NULL=boolean (true/false literal)<br>BOOL=boolean (true/false literal)</p><p>Let’s add the “id” partition key to the dictionary:</p><pre>snapshot_details_pull[&#39;id&#39;] = 2 #Integer value</pre><p>As a test, we attempt to add the item into the database table as an integer value and receive the following “ValidationException” error:</p><pre>Type mismatch for key id expected: S actual: N</pre><p>Add the value as a string instead to counter this error:</p><pre>snapshot_details_pull[&#39;id&#39;] = &#39;2&#39; #String value</pre><p>Finally, we’ll commit our dictionary to the DynamoDB table:</p><pre>response = table.put_item(Item=snapshot_details_pull)<br>response[&#39;ResponseMetadata&#39;][&#39;HTTPStatusCode&#39;]<br>200</pre><p>We can optionally check the “ResponseMetadata” field values to verify that our submission was successful (HTTP response code of 200 indicates a success).</p><p>Additionally, we can perform a “get_item” lookup on the table (may vary depending on your table’s “KeySchema”.</p><pre>table.get_item(Key={&#39;OwnerId&#39;:&#39;99999999999&#39;,&#39;snapshot_id&#39;:&#39;snap-aabbccddeeffgghhi&#39;})</pre><h3>Update an item</h3><p>Let’s also quickly explore updating this same item.</p><pre>tab.eupdate_item(<br>    Key={&#39;OwnerId&#39;:&#39;99999999999&#39;,&#39;snapshot_id&#39;:&#39;snap-aabbccddeeffgghhi&#39;},<br>    UpdateExpression=&#39;SET VolumeSize = :val1&#39;,<br>    ExpressionAttributeValues={<br>        &#39;:val1&#39;: 20<br>    }</pre><p>In this case, we are quickly updating the VolumeSize of this specific snapshot item from 10 to 20.</p><h3>References</h3><p><a href="https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html#:~:text=Once%20you%20have%20a%20DynamoDB.Table%20resource%20you%20can,25%20%2C%20%27account_type%27%20%3A%20%27standard_user%27%20%2C%20%7D%20%29">https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html#:~:text=Once%20you%20have%20a%20DynamoDB.Table%20resource%20you%20can,25%20%2C%20%27account_type%27%20%3A%20%27standard_user%27%20%2C%20%7D%20%29</a></p><p><a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.FilterExpression">https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.FilterExpression</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b22c985ab8cb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Setting up GitHub SSH access to push code]]></title>
            <link>https://medium.com/@epselon/setting-up-github-ssh-access-to-push-code-f273f8a55010?source=rss-fc573f9ba90a------2</link>
            <guid isPermaLink="false">https://medium.com/p/f273f8a55010</guid>
            <dc:creator><![CDATA[Dustin Hammond]]></dc:creator>
            <pubDate>Sat, 04 Mar 2023 22:03:52 GMT</pubDate>
            <atom:updated>2023-03-04T22:03:52.470Z</atom:updated>
            <content:encoded><![CDATA[<p>Here’s a quick article on how to setup your ability to commit and push code to your new github.com repository.</p><h3>Create a repository</h3><p>Create a new repository by clicking on the “New” button under the “repositories” section in the drop-down under your profile username at the top right of the screen.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HM92Fb49q-LXjcNUZ0sLaw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sI5pdsVGMuU7IwaBc20nRQ.png" /></figure><h3>Setup SSH access</h3><p>Proceed to setup SSH access by performing the following steps in order:</p><ol><li>Generate a new local SSH key on your system.</li></ol><ul><li>Use the “ssh-keygen” command to generate a keypair. In this example, we will be using the commonly used combination of RSA and a number of bits size of 4096.</li><li>Save the file under your users /home directory and within the hidden “.ssh” folder within the users home directory. In this case, we’re naming the new keypair “github_rsa_key” as a demonstration.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/755/1*8mV_HcFzf9OW-zPGAZcaww.png" /><figcaption>Relevant details are highlighted in the green squares</figcaption></figure><p>2. Add the public key that was generated to your GitHub profile.</p><ul><li>First, you will need to get the public key output by using the “cat” command against your new public key file.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/755/1*kBci76ckcN8qe1jdgkgnlQ.png" /></figure><ul><li>Next, navigate to your “Settings” page of your account and click on “SSH and GPG keys”.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YRwkyMBN79lVl8CpsPF-FA.png" /></figure><ul><li>Click “New SSH key” and paste in the contents of your public key that you retrieved from the “cat” command above.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GolGwinX-VpJenrD5QwJYw.png" /></figure><p>3. After the key is successfully added from the last step, return to the terminal and test accessibility using the following command:</p><ul><li>ssh -T git@github.com -i ~/.ssh/github_rsa_key</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/693/1*5O6A6bsNUe08fFpg36aXnw.png" /><figcaption>You will observe the “successfully authenticated” message if you performed the steps correctly.</figcaption></figure><ul><li>You can additionally verify that the appropriate “github.com” is being added by performing a “whois” lookup on the IP address noted from the SSH output above. In this case, 140.82.112.3.</li><li>The net range that belongs to GitHub,Inc at this point in time is 140.82.112.0/20 for which this IP address falls within.</li></ul><h3>Push code setup</h3><p>When you’re ready to push code up to your own repository, you may encounter an unexpected HTTP 403 error response. In this case, you just need some slight updates to your git config file located in your locally cloned directory’s hidden “.git” folder.</p><ul><li>Change the remote origin.url to be the SSH equivalent which can be acquired straight from the UI during the process of attempting to “git clone” the repository.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/994/1*kc_bvqAdF_nQAV6HyNFsow.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/523/1*cl2JwJuyjRSqRGQcGcjPDA.png" /><figcaption>In this example — we’re testing against my “cloudformation_templates” repository.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/515/1*STUazPzxwh6f4gmByx_biQ.png" /></figure><ul><li>Next — update your local SSH config file to account for the connections to the github.com domain by referencing the private key file you created earlier. (~/.ssh/config)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/1*8O3MfTFQUKthUTM6gRGw8g.png" /><figcaption>If the config file doesn’t exist, create a new file as I did here under the user’s /home/.ssh directory. If you do create it, also run “chmod 600 ~/.ssh/config” to ensure ownership settings are correct.</figcaption></figure><p>Finally, make your changes, commit and push and you should see a success!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/805/1*daYLMggLJdxI_y-M-ThPEg.png" /><figcaption>Successful push</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f273f8a55010" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Take down Production? How to respond if you made a big mistake.]]></title>
            <link>https://medium.com/@epselon/take-down-production-how-to-respond-if-you-made-a-big-mistake-16ebfd2cf44b?source=rss-fc573f9ba90a------2</link>
            <guid isPermaLink="false">https://medium.com/p/16ebfd2cf44b</guid>
            <category><![CDATA[outage]]></category>
            <category><![CDATA[incident-response]]></category>
            <category><![CDATA[production]]></category>
            <category><![CDATA[mistakes]]></category>
            <category><![CDATA[tech]]></category>
            <dc:creator><![CDATA[Dustin Hammond]]></dc:creator>
            <pubDate>Sat, 01 Feb 2020 04:07:25 GMT</pubDate>
            <atom:updated>2020-02-01T04:07:25.566Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PBqYMy9np58Pkyi9GXZ5MA.png" /><figcaption><a href="https://pixabay.com/illustrations/social-social-networks-1206614/">https://pixabay.com/illustrations/social-social-networks-1206614/</a></figcaption></figure><p>“What are you doing!?” my colleague asked me over the phone as I was in a sweaty panic.</p><p>“I accidentally disconnected the wrong fiber cable for a brief moment… I plugged it back in quickly once I realized I had disconnected the wrong port!” I said nervously. The loud fans of servers surrounding me probably drowned out a part of my answer I thought as I anxiously awaited his reply.</p><p>“It’s okay man… that’s why we have redundant links… just be more careful next time!” my colleague replied in a cheerful manner with a follow up chuckle.</p><p>I let out a huge sigh of relief and thanked him.</p><p>We hung up the phone and I cleaned up, this time being more careful to disconnect the correct cable.</p><p>It’s these types of situations that may arise during your career as an IT professional. Whether it is disconnecting the wrong cable like in my case, or whether it is running a small test that ends up causing a brief production outage, it is critical that you have the correct mindset to overcome.</p><p>Here are a few brief tips that can help you recover from an honest mistake.</p><h3>1. Stay calm</h3><p>It is very easy to quickly go into panic mode the moment you realize you’ve made a mistake. Realizing that this is a normal response to such an incident is perfectly normal! But you need to also recognize that while your stomach has that tingly something is wrong feeling, you need to be careful not to let it overtake you. Take a long, deep breath and tell yourself that things can be fixed and it will be okay. Trust me, the long deep breath really helps calm you down a little bit.</p><h3>2. Communicate the issue</h3><p>If you understand what you have done to cause the problem, you may be able to quickly fix the issue up front. In my case, I responded somewhat in a panic and reconnected the cable right away.</p><p>I don’t recommend this approach because you won’t be able to always fix the problem right away in such an incident. Instead, contact your colleages and let them know what happened. This is important because you may have just triggered a ton of different alerts that have them on a hunt to track down the sudden outage. Meanwhile, you’re sitting there in a sweaty panic wondering what you’re going to do and probably quite embarrassed and ashamed as well.</p><p>More often than not, your team is there to help you out! They will be glad and probably relieved to at least understand what caused the sudden alarm and they can begin assisting you in fixing the issue as soon as possible! You should never try and be a one man hero.</p><h3>3. Be honest</h3><p>This is a really important one. You should NEVER lie to your team and you should NEVER try and hide what you’ve done. You may get away with it, but you are setting yourself up for a dangerous precedent. Most systems are logged and in most cases, your actions can be tracked down in due time through correlation efforts. It is better to confess up front and set your team down the road to fixing the issue rather than hiding it. In my opinion, lying and hiding the mistakes you’ve made is practically a terminating offense. You can potentially never be trusted again if you’re found out. Do NOT be that person!</p><h3>4. Be quick</h3><p>The moment you realize you’ve made a mistake, be quick about following through with fixing it! Do not sit around and think about what you should have or could have done to cause it right then. Time is of the essence here and it is critical that you do the right thing and stay calm, communicate, and confess to the mistake. Most businesses depend on production to remain online and every second is potential to cause financial loss to the companies bottom line. If the outage is long enough, the results could be catastrophic to the business.</p><h3>5. Learn from your mistake</h3><p>After the issue has been resolved, take a moment to reassess what the timeline of events were that caused this in the first place. You will quickly realize and understand what you need to do in the future to avoid it! Some tips to further learn and understand is to document the incident, generally in the form of a <a href="https://www.pagerduty.com/resources/learn/post-mortem-incident-report/">post-mortem</a>. <strong>PagerDuty</strong> provides a very great explanation of what a post-mortem is and how you may go about conducting one.</p><p>Learn, react, and adapt. You will carry forth wisdom and experience that you can then confidently carry on your shoulders with the knowledge and understanding of how to avoid it in the future. And yes, you should avoid it in the future! Making the same mistakes over and over is certainly a doomed path. Be very sure to learn from your mistake!</p><h3>Summary</h3><p>We all make mistakes, it is practically human nature! On a long enough timeline, we are all bound to slip up every once in awhile. That is normal! It is important to accept this and be forthcoming with your mistake if you’ve caused an outage rather than sit on it and try and hide it or fix it on your own. You may be wasting your colleagues time as they desperately respond to alarms while you already possess the knowledge to fix the issue.</p><p>Stay focused, be honest, and work with your team to fix the outage in a timely manner. The business is depending on you to be the caretakers of their systems so treat them with respect and do not try and be slick by cleaning up and sweeping things under the rug. Things are bound to come back at you even harder than if you would have just come out and confessed straight away.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=16ebfd2cf44b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AWS EKS: Managed setup with CloudFormation]]></title>
            <link>https://medium.com/@epselon/aws-eks-managed-setup-with-cloudformation-97461300e952?source=rss-fc573f9ba90a------2</link>
            <guid isPermaLink="false">https://medium.com/p/97461300e952</guid>
            <category><![CDATA[ek]]></category>
            <category><![CDATA[template]]></category>
            <category><![CDATA[cloudformation]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[kubernetes]]></category>
            <dc:creator><![CDATA[Dustin Hammond]]></dc:creator>
            <pubDate>Sat, 26 Oct 2019 06:09:25 GMT</pubDate>
            <atom:updated>2019-10-27T19:15:20.645Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/638/1*MoIeHG0NzU7sZ2NHX_TGvA.png" /></figure><h3>Overview</h3><p>In this post, we will review how to setup the AWS EKS service on your AWS account. This will be created in a single AWS region but you can reuse the material we go over here on a per region basis. We will be working with the CloudFormation service which will help us build and maintain the cluster itself as well as the networking infrastructure required to logically contain our resources. Finally, we will build the control plane within the same template and run it all as one single stack.</p><h3>The EKS IAM Role</h3><p>First and foremost, we are required to create a new IAM role that will allow the EKS service to assume role to your AWS account to help manage the associated resources.</p><pre>Resources:<br>  EKSIAMRole:<br>    Type: &#39;AWS::IAM::Role&#39;<br>    Properties:<br>      AssumeRolePolicyDocument:<br>        Version: 2012-10-17<br>        Statement:<br>          - Effect: Allow<br>            Principal:<br>              Service:<br>                - eks.amazonaws.com<br>            Action:<br>              - &#39;sts:AssumeRole&#39;<br>      RoleName: !Ref EKSIAMRoleName<br>      ManagedPolicyArns:<br>        - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy<br>        - arn:aws:iam::aws:policy/AmazonEKSServicePolicy</pre><p>Briefly going over the above template extract, we are creating a new IAM “role” resource and allowing the EKS service to use the role. Additionally we have attached two (existing) managed IAM policies that are required for the EKS service to properly manage the upcoming cluster. A managed policy is a built-in policy already available within AWS.</p><h3>The EKS network infrastructure</h3><p>Next, we are required to build the EKS network infrastructure that the EKS cluster will reside in. This should be created next in-line and a fully configured template for this is already available on the official AWS documentation website. We will link it here for good measure.</p><p><a href="https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-10-08/amazon-eks-vpc-private-subnets.yaml">https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-10-08/amazon-eks-vpc-private-subnets.yaml</a></p><p>The three things you are normally required to make a note of as a result of the network build are the following:</p><ul><li>VPC ID</li><li>SecurityGroup</li><li>Subnet IDs</li></ul><p>These values will be required when it comes time to generate the actual EKS cluster.</p><p>In our case though, we will be skipping even the need to collect those details as we will just be referencing all of this in the CloudFormation template. Just note that the template is built in such a way that the order of operations is to create the IAM role and the network infrastructure before finally creating the EKS cluster itself.</p><h3>EKS Cluster: Control Plane</h3><p>Creating the control plane piece of this is probably the easiest part. Why? Because it is just the culmination of the previous resources as we noted in the last section. Since we’re using a CloudFormation template though, we are going to let the template do all of the work for us in specifying the associated subnets, security group, and IAM role we want to use for the cluster creation.It’s annoying to have to write those values down somewhere for later as the official documentation suggests.</p><p>We will simply append the following to our template:</p><pre>EKSCluster:<br>  Type: AWS::EKS::Cluster<br>  Properties:<br>    Name: !Ref EKSClusterName<br>    RoleArn:<br>      &quot;Fn::GetAtt&quot;: [&quot;EKSIAMRole&quot;, &quot;Arn&quot;]<br>    ResourcesVpcConfig:<br>      SecurityGroupIds:<br>      - !Ref ControlPlaneSecurityGroup<br>      SubnetIds:<br>      - !Ref PublicSubnet01<br>      - !Ref PublicSubnet02<br>      - !Ref PrivateSubnet01<br>      - !Ref PrivateSubnet02<br>  DependsOn: [EKSIAMRole, PublicSubnet01, PublicSubnet02, PrivateSubnet01, PrivateSubnet02, ControlPlaneSecurityGroup]</pre><p>At this point, we now have a full and complete Cloudformation template to build the IAM Role, the network infrastructure, and the master node/control plane for our EKS cluster. Next up is the worker nodes.</p><h4>Control Plane template (final):</h4><p>Here is our final CloudFormation template to build the IAM Role, the network infrastructure, and the control plane for our new EKS cluster. Remember this is a combination of our IAM Role template, the EKS Cluster template, and the AWS provided network template.</p><pre>---<br>AWSTemplateFormatVersion: &#39;2010-09-09&#39;</pre><pre>Parameters:</pre><pre>  EKSIAMRoleName:<br>    Type: String<br>    Description: The name of the IAM role for the EKS service to assume.</pre><pre>  EKSClusterName:<br>    Type: String<br>    Description: The desired name of your AWS EKS Cluster.<br>    <br>  VpcBlock:<br>    Type: String<br>    Default: 192.168.0.0/16<br>    Description: The CIDR range for the VPC. This should be a valid private (RFC 1918) CIDR range.</pre><pre>  PublicSubnet01Block:<br>    Type: String<br>    Default: 192.168.0.0/18<br>    Description: CidrBlock for public subnet 01 within the VPC</pre><pre>  PublicSubnet02Block:<br>    Type: String<br>    Default: 192.168.64.0/18<br>    Description: CidrBlock for public subnet 02 within the VPC</pre><pre>  PrivateSubnet01Block:<br>    Type: String<br>    Default: 192.168.128.0/18<br>    Description: CidrBlock for private subnet 01 within the VPC</pre><pre>  PrivateSubnet02Block:<br>    Type: String<br>    Default: 192.168.192.0/18<br>    Description: CidrBlock for private subnet 02 within the VPC</pre><pre>Metadata:<br>  AWS::CloudFormation::Interface:<br>  ParameterGroups:<br>    -<br>      Label:<br>        default: &quot;Worker Network Configuration&quot;<br>      Parameters:<br>        - VpcBlock<br>        - PublicSubnet01Block<br>        - PublicSubnet02Block<br>        - PrivateSubnet01Block<br>        - PrivateSubnet02Block</pre><pre>Resources:<br>  EKSIAMRole:<br>    Type: &#39;AWS::IAM::Role&#39;<br>    Properties:<br>      AssumeRolePolicyDocument:<br>        Version: 2012-10-17<br>        Statement:<br>          - Effect: Allow<br>          Principal:<br>            Service:<br>              - eks.amazonaws.com<br>          Action:<br>            - &#39;sts:AssumeRole&#39;<br>      RoleName: !Ref EKSIAMRoleName<br>      ManagedPolicyArns:<br>        - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy<br>        - arn:aws:iam::aws:policy/AmazonEKSServicePolicy</pre><pre>  VPC:<br>    Type: AWS::EC2::VPC<br>    Properties:<br>      CidrBlock:  !Ref VpcBlock<br>      EnableDnsSupport: true<br>      EnableDnsHostnames: true<br>    Tags:<br>    - Key: Name<br>      Value: !Sub &#39;${AWS::StackName}-VPC&#39;</pre><pre>  InternetGateway:<br>    Type: &quot;AWS::EC2::InternetGateway&quot;<br>    VPCGatewayAttachment:<br>    Type: &quot;AWS::EC2::VPCGatewayAttachment&quot;<br>    Properties:<br>      InternetGatewayId: !Ref InternetGateway<br>      VpcId: !Ref VPC</pre><pre>  PublicRouteTable:<br>    Type: AWS::EC2::RouteTable<br>    Properties:<br>      VpcId: !Ref VPC<br>    Tags:<br>    - Key: Name<br>      Value: Public Subnets<br>    - Key: Network<br>      Value: Public</pre><pre><br>  PrivateRouteTable01:<br>    Type: AWS::EC2::RouteTable<br>    Properties:<br>      VpcId: !Ref VPC<br>    Tags:<br>    - Key: Name<br>      Value: Private Subnet AZ1<br>    - Key: Network<br>      Value: Private01</pre><pre><br>  PrivateRouteTable02:<br>    Type: AWS::EC2::RouteTable<br>    Properties:<br>      VpcId: !Ref VPC<br>    Tags:<br>    - Key: Name<br>      Value: Private Subnet AZ2<br>    - Key: Network<br>      Value: Private02</pre><pre>  PublicRoute:<br>    DependsOn: VPCGatewayAttachment<br>    Type: AWS::EC2::Route<br>      Properties:<br>      RouteTableId: !Ref PublicRouteTable<br>      DestinationCidrBlock: 0.0.0.0/0<br>      GatewayId: !Ref InternetGateway</pre><pre>  PrivateRoute01:<br>    DependsOn:<br>    - VPCGatewayAttachment<br>    - NatGateway01<br>    Type: AWS::EC2::Route<br>    Properties:<br>      RouteTableId: !Ref PrivateRouteTable01<br>      DestinationCidrBlock: 0.0.0.0/0<br>      NatGatewayId: !Ref NatGateway01</pre><pre>  PrivateRoute02:<br>    DependsOn:<br>    - VPCGatewayAttachment<br>    - NatGateway02<br>    Type: AWS::EC2::Route<br>    Properties:<br>      RouteTableId: !Ref PrivateRouteTable02<br>      DestinationCidrBlock: 0.0.0.0/0<br>      NatGatewayId: !Ref NatGateway02</pre><pre>  NatGateway01:<br>    DependsOn:<br>    - NatGatewayEIP1<br>    - PublicSubnet01<br>    - VPCGatewayAttachment<br>    Type: AWS::EC2::NatGateway<br>    Properties:<br>      AllocationId: !GetAtt &#39;NatGatewayEIP1.AllocationId&#39;<br>      SubnetId: !Ref PublicSubnet01<br>    Tags:<br>    - Key: Name<br>      Value: !Sub &#39;${AWS::StackName}-NatGatewayAZ1&#39;</pre><pre>  NatGateway02:<br>    DependsOn:<br>    - NatGatewayEIP2<br>    - PublicSubnet02<br>    - VPCGatewayAttachment<br>    Type: AWS::EC2::NatGateway<br>    Properties:<br>    AllocationId: !GetAtt &#39;NatGatewayEIP2.AllocationId&#39;<br>    SubnetId: !Ref PublicSubnet02<br>    Tags:<br>    - Key: Name<br>      Value: !Sub &#39;${AWS::StackName}-NatGatewayAZ2&#39;</pre><pre>  NatGatewayEIP1:<br>    DependsOn:<br>    - VPCGatewayAttachment<br>    Type: &#39;AWS::EC2::EIP&#39;<br>    Properties:<br>      Domain: vpc</pre><pre>  NatGatewayEIP2:<br>    DependsOn:<br>    - VPCGatewayAttachment<br>    Type: &#39;AWS::EC2::EIP&#39;<br>    Properties:<br>      Domain: vpc</pre><pre>  PublicSubnet01:<br>    Type: AWS::EC2::Subnet<br>    Metadata:<br>      Comment: Subnet 01<br>    Properties:<br>      AvailabilityZone:<br>        Fn::Select:<br>        - &#39;0&#39;<br>        - Fn::GetAZs:<br>          Ref: AWS::Region<br>        CidrBlock:<br>          Ref: PublicSubnet01Block<br>        VpcId:<br>          Ref: VPC<br>    Tags:<br>    - Key: Name<br>      Value: !Sub &quot;${AWS::StackName}-PublicSubnet01&quot;</pre><pre>  PublicSubnet02:<br>    Type: AWS::EC2::Subnet<br>    Metadata:<br>      Comment: Subnet 02<br>    Properties:<br>      AvailabilityZone:<br>        Fn::Select:<br>        - &#39;1&#39;<br>        - Fn::GetAZs:<br>          Ref: AWS::Region<br>        CidrBlock:<br>          Ref: PublicSubnet02Block<br>        VpcId:<br>          Ref: VPC<br>    Tags:<br>    - Key: Name<br>      Value: !Sub &quot;${AWS::StackName}-PublicSubnet02&quot;</pre><pre>  PrivateSubnet01:<br>    Type: AWS::EC2::Subnet<br>    Metadata:<br>      Comment: Subnet 03<br>    Properties:<br>      AvailabilityZone:<br>        Fn::Select:<br>        - &#39;0&#39;<br>        - Fn::GetAZs:<br>          Ref: AWS::Region<br>        CidrBlock:<br>          Ref: PrivateSubnet01Block<br>        VpcId:<br>          Ref: VPC<br>    Tags:<br>    - Key: Name<br>      Value: !Sub &quot;${AWS::StackName}-PrivateSubnet01&quot;<br>    - Key: &quot;kubernetes.io/role/internal-elb&quot;<br>      Value: 1</pre><pre>  PrivateSubnet02:<br>    Type: AWS::EC2::Subnet<br>    Metadata:<br>      Comment: Private Subnet 02<br>    Properties:<br>      AvailabilityZone:<br>        Fn::Select:<br>        - &#39;1&#39;<br>        - Fn::GetAZs:<br>          Ref: AWS::Region<br>        CidrBlock:<br>          Ref: PrivateSubnet02Block<br>        VpcId:<br>          Ref: VPC<br>    Tags:<br>    - Key: Name<br>      Value: !Sub &quot;${AWS::StackName}-PrivateSubnet02&quot;<br>    - Key: &quot;kubernetes.io/role/internal-elb&quot;<br>      Value: 1</pre><pre>  PublicSubnet01RouteTableAssociation:<br>    Type: AWS::EC2::SubnetRouteTableAssociation<br>    Properties:<br>      SubnetId: !Ref PublicSubnet01<br>      RouteTableId: !Ref PublicRouteTable</pre><pre>  PublicSubnet02RouteTableAssociation:<br>    Type: AWS::EC2::SubnetRouteTableAssociation<br>    Properties:<br>      SubnetId: !Ref PublicSubnet02<br>      RouteTableId: !Ref PublicRouteTable</pre><pre>  PrivateSubnet01RouteTableAssociation:<br>    Type: AWS::EC2::SubnetRouteTableAssociation<br>    Properties:<br>      SubnetId: !Ref PrivateSubnet01<br>      RouteTableId: !Ref PrivateRouteTable01</pre><pre>  PrivateSubnet02RouteTableAssociation:<br>    Type: AWS::EC2::SubnetRouteTableAssociation<br>    Properties:<br>      SubnetId: !Ref PrivateSubnet02<br>      RouteTableId: !Ref PrivateRouteTable02</pre><pre>  ControlPlaneSecurityGroup:<br>    Type: AWS::EC2::SecurityGroup<br>    Properties:<br>      GroupDescription: Cluster communication with worker nodes<br>      VpcId: !Ref VPC</pre><pre>  EKSCluster:<br>    Type: AWS::EKS::Cluster<br>    Properties:<br>      Name: !Ref EKSClusterName<br>      RoleArn:<br>        &quot;Fn::GetAtt&quot;: [&quot;EKSIAMRole&quot;, &quot;Arn&quot;]<br>        ResourcesVpcConfig:<br>          SecurityGroupIds:<br>          - !Ref ControlPlaneSecurityGroup<br>          SubnetIds:<br>          - !Ref PublicSubnet01<br>          - !Ref PublicSubnet02<br>          - !Ref PrivateSubnet01<br>          - !Ref PrivateSubnet02<br>    DependsOn: [EKSIAMRole, PublicSubnet01, PublicSubnet02, PrivateSubnet01, PrivateSubnet02, ControlPlaneSecurityGroup]</pre><pre>Outputs:<br>  SubnetIds:<br>    Description: Subnets IDs in the VPC<br>    Value: !Join [ &quot;,&quot;, [ !Ref PublicSubnet01, !Ref PublicSubnet02, !Ref PrivateSubnet01, !Ref PrivateSubnet02 ] ]</pre><pre>  SecurityGroups:<br>    Description: Security group for the cluster control plane communication with worker nodes<br>    Value: !Join [ &quot;,&quot;, [ !Ref ControlPlaneSecurityGroup ] ]</pre><pre>  VpcId:<br>    Description: The VPC Id<br>    Value: !Ref VPC</pre><h3>EKS Cluster: Worker nodes</h3><p>Before we have a fully working cluster, we obviously need to create the actual worker nodes! This is required to be a separate template because the creation of these nodes has the pre-requisite of the cluster actually existing first! While technically we could leverage the “DependsOn” attribute that we’ve been using, you must remember that you may also wish to update the stack at a later date and you don’t want to mess with the foundations of your cluster as we’ve created above if you can avoid it.</p><p>The worker node template that AWS has built is pretty straight forward and I would recommend leveraging it as a separate stack. Here’s the link to that YAML file:</p><p><a href="https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-10-08/amazon-eks-nodegroup.yaml">https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-10-08/amazon-eks-nodegroup.yaml</a></p><p>We will go over deploying this template as well after we’ve stood up our Control Plane stack.</p><h3>Deploying your CloudFormation template(s)</h3><p>A quick reminder on how to deploy your template within your AWS account. The following steps apply:</p><ol><li>Login to your AWS account and select the appropriate region you will be working out of at the top right.</li><li>On the services search bar, type “cloudformation” and select the CloudFormation service.</li><li>Leave the default “template is ready” selected and then click “Upload a template file” to select your YAML file.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bfY1IxEKVK2pNaWvNLzm8w.png" /></figure><p>4. Fill in the required fields on the next page and leave the defaults for the ones that are populated if desired.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GLVmc5iXc9G8mwtw5mGzKw.png" /></figure><p>5. Proceed to create the stack and ensure that you specify and agree to the fact that it will create IAM resources on the account.</p><p>6. Once the stack has completed, you should see a “CREATE_COMPLETE” status for the newly deployed stack.</p><p>7. You can browse to the EKS service to see your newly deployed resources for the control plane.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rkAA6GcDteq0VrsoWKAeAg.png" /></figure><p>Now it’s time to deploy that worker stack that we talked about earlier.</p><p>One step we need to do with the worker node template is create an EC2 key pair that we will need to specify on the template creation page. This key will allow you to be able to SSH into your worker nodes for troubleshooting purposes. AWS currently does not support creating a key pair with CloudFormation so it has to be done elsewhere. In this case, we will create a key pair through the AWS console. Follow the steps below to do so:</p><ul><li>Browse to the EC2 service</li><li>Select “Key Pairs”</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VK9OsHmamMqYiL75YbMLOQ.png" /></figure><ul><li>Select “Create Key Pair” and provide the key pair with a name.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1HDhzqE-9uIDMeQdBhl6Pw.png" /></figure><p>At this point, you can follow the same steps as before but this time you can reference the S3 link in the stack creation page.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YVVXtNgIWWxQjBQ_0f5lZg.png" /></figure><p>Step through the fields in the template, this time you will need to specify a name for the node group as well as select the associated VPC and subnets for the worker group.</p><p>Create the stack in the same manner as before and at the end, you will have two CloudFormation stacks. One for the control plane and one of the worker nodes.</p><p>Enjoy! Next time we will go over how to authenticate to your new cluster!</p><h3>References:</h3><p><a href="https://docs.aws.amazon.com/eks/latest/userguide/getting-started-console.html">https://docs.aws.amazon.com/eks/latest/userguide/getting-started-console.html</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=97461300e952" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AWS GuardDuty: Managed setup with CloudFormation]]></title>
            <link>https://medium.com/@epselon/aws-guardduty-managed-setup-with-cloudformation-41a38e17aa2f?source=rss-fc573f9ba90a------2</link>
            <guid isPermaLink="false">https://medium.com/p/41a38e17aa2f</guid>
            <category><![CDATA[infrastructure]]></category>
            <category><![CDATA[guard-duty]]></category>
            <category><![CDATA[template]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cloudformation]]></category>
            <dc:creator><![CDATA[Dustin Hammond]]></dc:creator>
            <pubDate>Wed, 17 Jul 2019 05:47:01 GMT</pubDate>
            <atom:updated>2020-02-04T03:23:30.866Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/618/1*TrRD9hWohrEKSYSjkxq-qw.png" /></figure><h3>Overview</h3><p>This page will serve as a brief introduction to AWS GuardDuty. You will find the reference links to the official documentation at the bottom of this page as well as my public Github.</p><p>I want to briefly go over some of the basic settings you can configure on your AWS account(s). Specifically, I want to go over how you can manage your accounts GuardDuty configuration with automation and management tools. In this post, we will specifically go over the AWS command line interface as well as AWS CloudFormation.</p><p>We will skip the introduction of what AWS GuardDuty is in this particular posting.</p><h3>Getting Started with the AWS CLI</h3><p>Pre-requisites:</p><ul><li>Have administrative access to your AWS account</li><li>Have the AWS CLI installed on your local machine. (<a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html">https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html</a>)</li></ul><p>One you have the AWS CLI configured on your local machine with the appropriate administrative access, it’s time to dive into the configuration.</p><p>Type “aws guardduty help” to see the list of commands available. Note that with AWS commands, each layer has a set of help commands so if you have additional questions about a specific parameter simply add the “help” argument at the end. For example, in this case, we will need to create a detector.</p><p>Type the following command:</p><pre>aws guardduty create-detector --enable</pre><p>If you wanted to understand the details of the above command, you can simply add <strong>help</strong> at the end.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ar_PB11vc51yTj9wDfAbjg.png" /></figure><p><em>Note: You can only have one detector enabled on your account at a time per region.</em></p><p>If you log back into your AWS account console, you will see that GuardDuty has now been enabled. You can generate sample findings with the following command:</p><pre>aws guardduty create-sample-findings --detector-id &lt;your detector id here&gt;</pre><p><em>Note: You will receive your detector-id from our previous “create-detector” command. If you lost that information, you can retrieve the detector-id again via the the command</em></p><pre>aws guardduty list-detectors</pre><p>You may have noticed we just accepted the default settings for the detector when creating it via the above command. We can update the detector to change the publishing frequency to say 15 minutes for example via the following command:</p><pre>aws guardduty update-detector --finding-publishing-frequency FIFTEEN_MINUTES</pre><p>The command line provides a useful and quick method of generating a new GuardDuty detector. But that’s really all it provides, you have to manually provision and maintain this configuration overtime. Most organizations are moving towards Infrastructure as code, and you can manage GuardDuty as well through this method. We’re going to go over a useful tool that can provide more organization around what you deploy within AWS in relation to AWS GuardDuty.</p><h3>Deploy GuardDuty with CloudFormation</h3><p>AWS provides a service called CloudFormation. This service provides the administrator with the ability to deploy “stacks” of resources all at once or in steps. The most useful thing about deploying with CloudFormation is that everything will be maintained through the stack including updates to the stack as well as deleting the stack. You can delete your entire stack with a few simple clicks. You can also specify which resources you may wish to retain.</p><p>In relation to GuardDuty, we can produce a detector similar to what we provided via the command line above with a very quick template. We will be using the YAML format here as it is more constructive and easy to work with and allows for comments to be written inline.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6PTwrUwfIaaG3ytYq_ooLw.png" /><figcaption><a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-guardduty-detector.html#cfn-guardduty-detector-findingpublishingfrequency">https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-guardduty-detector.html</a></figcaption></figure><p>The above is a very basic deployment of the GuardDuty detector. We can validate the enablement of the service through the command line via the command “<strong>aws guardduty list-detectors</strong>”. This will return a list of detectors (only a single detector is allowed per AWS Region at this point in time). From here, you can leverage the command line to pull back addintional configuration details on the detector via the command</p><pre>aws guardduty get-detector --detector-id &lt;your detector id here&gt;</pre><h3>Manage the event flow</h3><p>What good is a GuardDuty detector if you don’t manage your event structure as well?</p><p>We’ll make a quick update to our CloudFormation template to setup a process flow to send events to an SNS topic so that we can get notified of any findings our newly created detector detects.</p><p><strong>Setup Overview</strong></p><p>The following CloudFormation template will create the following setup with the only pre-requsite being an existing SQS Standard Queue.</p><ul><li>Creates an SNS Topic along with an access policy for that topic to allow for events.amazonaws.com to publish to the topic.</li><li>Creates a CloudWatch event rule that contains an event pattern to match events from aws.guardduty.</li><li>Sets up a target for the CloudWatch event rule to point to our previously mentioned SNS topic.</li><li>Finally, it subscribes our existing SQS queue to the topic so that it will receive event messages anytime GuardDuty detections are detected.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/793147909c02f4fdae893faccf8e7700/href">https://medium.com/media/793147909c02f4fdae893faccf8e7700/href</a></iframe><p>You can test this CloudFormation sample template by following these steps:</p><ol><li>Login to your AWS Account and navigate to the GuardDuty service</li><li>Click on <strong>Settings</strong> and then click on <strong>Generate Sample Findings</strong></li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2jGtNzxjzDLVqb6n0MBawQ.png" /></figure><p>3. Navigate over to your SQS Queue within the SQS service.</p><p>4. Monitor the queue for inbound messages within the next few minutes after having clicked on the sample findings generation button.</p><h3>Final Thoughts</h3><p>This is a brief configuration you can leverage when setting up your GuardDuty environment. You can subscribe any number of emails or endpoints to your SNS Topic so that your applications or monitoring solutions can be notified of GuardDuty findings.</p><p>You may also wish to rope in the detector creation into the above template to wrap it all up as one CloudFormation stack which also works.</p><p>There are additional configuration settings we can setup with GuardDuty that we can go over in more detail next time.</p><p>Experiment to your hearts content!</p><p><strong>References</strong>:</p><ul><li><a href="https://aws.amazon.com/guardduty/">Intelligent Threat Detection - Amazon GuardDuty - AWS</a></li><li><a href="https://aws.amazon.com/cloudformation/">Provision Infrastructure as Code - AWS CloudFormation - AWS</a></li><li><a href="https://github.com/dhammond22222/cloudformation_templates">dhammond22222/cloudformation_templates</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=41a38e17aa2f" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>