<?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: Mike Graff</title>
    <description>The latest articles on DEV Community by Mike Graff (@michaelegraff).</description>
    <link>https://dev.to/michaelegraff</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%2F637167%2Ff65f49f9-feda-451b-9d10-b9c8cbc1ebbd.jpeg</url>
      <title>DEV Community: Mike Graff</title>
      <link>https://dev.to/michaelegraff</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michaelegraff"/>
    <language>en</language>
    <item>
      <title>Has Generative AI ruined the re:Invent experience?</title>
      <dc:creator>Mike Graff</dc:creator>
      <pubDate>Thu, 03 Oct 2024 21:12:48 +0000</pubDate>
      <link>https://dev.to/aws-builders/has-generative-ai-ruined-the-reinvent-experience-1k75</link>
      <guid>https://dev.to/aws-builders/has-generative-ai-ruined-the-reinvent-experience-1k75</guid>
      <description>&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;I've been attending re:Invent every year since 2015, and while the conference has its share of issues, I've always returned because I've felt the benefits far outweigh the drawbacks.  It seems as if Generative AI related sessions have taken over re:Invent, to the detriment of other topics.&lt;/p&gt;

&lt;h2&gt;AWS re:Invent - a learning conference&lt;/h2&gt;

&lt;p&gt;AWS re:Invent is...a lot to deal with.  Yes, the session catalog is terrible to navigate. So much so that it has inspired some fellow Community Builders to step in with &lt;a href="https://reinvent-planner.cloud" title="" rel="noopener noreferrer"&gt;the creation of third party tools&lt;/a&gt; to fill the gap.  Sure, the session registration system is a total mess and has been for years.  Not to mention it completely disadvantages folks from different countries that live in different time zones.  Lastly, the huge crowds and navigating across multiple venues up and down the strip makes things logistically painful.  &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%2Fcloudyadvice.com%2Fwp-content%2Fuploads%2F2024%2F10%2Freinvent-crowds-1024x436.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%2Fcloudyadvice.com%2Fwp-content%2Fuploads%2F2024%2F10%2Freinvent-crowds-1024x436.jpg" alt="" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However at the end of the day it has always been the high quality and deeply technical nature of the content, the variety of topics covered, and the outstanding networking opportunities that kept me coming back year after year.  (Not to mention the fantastic musical performances at re:Play).&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%2Fcloudyadvice.com%2Fwp-content%2Fuploads%2F2024%2F10%2FIMG_8683-1024x576.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%2Fcloudyadvice.com%2Fwp-content%2Fuploads%2F2024%2F10%2FIMG_8683-1024x576.jpg" alt="Thievery Corporation preforming at AWS re:Play party in 2022." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However in 2024 Generative AI has become the dominant topic in the tech world.  It has sucked all the oxygen out of the room at most tech conferences, and that trend seems to have extended to re:Invent as well.  Let's dive in...&lt;/p&gt;

&lt;h2&gt;Generative AI related sessions have taken over re:Invent&lt;/h2&gt;

&lt;p&gt;I'm always excited when the re:Invent session catalog gets released, and this year was no different.    However that excitement diminished significantly when I started looking at the breakdown of session subjects.  I quickly discovered that the catalog is dominated by AI topics.  More worrisome, several of the areas I'm passionate about (like Networking and Storage) have a shockingly low number of sessions this year. Here's a breakdown of the 2378 sessions currently listed in the re:Invent catalog by session topic:&lt;/p&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;Number of Sessions&lt;/th&gt;
&lt;th&gt;Percentage of Total&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AI/ML&lt;/td&gt;
&lt;td&gt;820&lt;/td&gt;
&lt;td&gt;34%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Analytics&lt;/td&gt;
&lt;td&gt;223&lt;/td&gt;
&lt;td&gt;9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;243&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business Applications&lt;/td&gt;
&lt;td&gt;129&lt;/td&gt;
&lt;td&gt;5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud Operations&lt;/td&gt;
&lt;td&gt;237&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compute&lt;/td&gt;
&lt;td&gt;153&lt;/td&gt;
&lt;td&gt;6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content Delivery&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer Enablement&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databases&lt;/td&gt;
&lt;td&gt;138&lt;/td&gt;
&lt;td&gt;6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DevOps &amp;amp; Developer Experience&lt;/td&gt;
&lt;td&gt;214&lt;/td&gt;
&lt;td&gt;9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;End User Computing&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;0.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hybrid Cloud&lt;/td&gt;
&lt;td&gt;37&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IoT&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;td&gt;3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Migration &amp;amp; Modernization&lt;/td&gt;
&lt;td&gt;234&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Networking&lt;/td&gt;
&lt;td&gt;70&lt;/td&gt;
&lt;td&gt;3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New to AWS&lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security, Compliance, and Identity&lt;/td&gt;
&lt;td&gt;227&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serverless &amp;amp; Containers&lt;/td&gt;
&lt;td&gt;185&lt;/td&gt;
&lt;td&gt;8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;111&lt;/td&gt;
&lt;td&gt;5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Training &amp;amp; Certification&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;1%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;em&gt;re:Invent 2024 session catalog breakdown by topic area.  Note that sessions are often tagged to more than one topic area.&lt;/em&gt;






&lt;p&gt;As you can see AI/ML topics currently make up whopping 34% of the session catalog.  In addition, because AWS will tag the same session with multiple topics, a fair number of the sessions in other topic areas are also AI related.  &lt;/p&gt;

&lt;h2&gt;Historical Trend&lt;/h2&gt;

&lt;p&gt;The AI takeover trend is even better illustrated when you compare the current session catalog to the catalogs from the past few years.  (A big shout out to my fellow AWS Community Builder Raphael Manke for providing 2022 and 2023 session catalog data).  Take a look at the trend graph for the various topic areas:&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%2Fcloudyadvice.com%2Fwp-content%2Fuploads%2F2024%2F10%2FReinvent-session-analysis.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%2Fcloudyadvice.com%2Fwp-content%2Fuploads%2F2024%2F10%2FReinvent-session-analysis.jpg" alt="A graph illustrating the trend on the number of sessions per topic area from 2022 to 2024" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a further detailed breakdown of selected session topic areas and the percentage change from 2022 to 2024:&lt;/p&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Topic Area&lt;/th&gt;
&lt;th&gt;2022&lt;/th&gt;
&lt;th&gt;2023&lt;/th&gt;
&lt;th&gt;2024&lt;/th&gt;
&lt;th&gt;Change 2022 &lt;br&gt;to 2024&lt;/th&gt;
&lt;th&gt;Percentage &lt;br&gt;change&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AI/ML&lt;/td&gt;
&lt;td&gt;417&lt;/td&gt;
&lt;td&gt;768&lt;/td&gt;
&lt;td&gt;820&lt;/td&gt;
&lt;td&gt;403&lt;/td&gt;
&lt;td&gt;52%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;314&lt;/td&gt;
&lt;td&gt;309&lt;/td&gt;
&lt;td&gt;243&lt;/td&gt;
&lt;td&gt;-71&lt;/td&gt;
&lt;td&gt;-23%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud Operations&lt;/td&gt;
&lt;td&gt;367&lt;/td&gt;
&lt;td&gt;304&lt;/td&gt;
&lt;td&gt;236&lt;/td&gt;
&lt;td&gt;-131&lt;/td&gt;
&lt;td&gt;-43%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compute&lt;/td&gt;
&lt;td&gt;237&lt;/td&gt;
&lt;td&gt;209&lt;/td&gt;
&lt;td&gt;153&lt;/td&gt;
&lt;td&gt;-84&lt;/td&gt;
&lt;td&gt;-40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer Enablement&lt;/td&gt;
&lt;td&gt;165&lt;/td&gt;
&lt;td&gt;76&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;-131&lt;/td&gt;
&lt;td&gt;-172%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databases&lt;/td&gt;
&lt;td&gt;272&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;137&lt;/td&gt;
&lt;td&gt;-135&lt;/td&gt;
&lt;td&gt;-68%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DevOps&lt;/td&gt;
&lt;td&gt;370&lt;/td&gt;
&lt;td&gt;263&lt;/td&gt;
&lt;td&gt;214&lt;/td&gt;
&lt;td&gt;-156&lt;/td&gt;
&lt;td&gt;-59%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EUC&lt;/td&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;-49&lt;/td&gt;
&lt;td&gt;-148%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hybrid Cloud&lt;/td&gt;
&lt;td&gt;164&lt;/td&gt;
&lt;td&gt;82&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;-128&lt;/td&gt;
&lt;td&gt;-156%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Networking &amp;amp; Content Delivery&lt;/td&gt;
&lt;td&gt;238&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;-137&lt;/td&gt;
&lt;td&gt;-107%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serverless &amp;amp; Containers&lt;/td&gt;
&lt;td&gt;311&lt;/td&gt;
&lt;td&gt;292&lt;/td&gt;
&lt;td&gt;185&lt;/td&gt;
&lt;td&gt;-126&lt;/td&gt;
&lt;td&gt;-43%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;291&lt;/td&gt;
&lt;td&gt;168&lt;/td&gt;
&lt;td&gt;112&lt;/td&gt;
&lt;td&gt;-179&lt;/td&gt;
&lt;td&gt;-107%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Training &amp;amp; Certification&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;92&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;-72&lt;/td&gt;
&lt;td&gt;-78%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;em&gt;re:Invent Session Catalog for the past three years, broken down by topic area&lt;/em&gt;






&lt;p&gt;The number of AI/ML sessions has essentially doubled since 2022.  Now I can't really blame AWS for this, as I already stated that is where all the buzz has been for the past 18 months so it makes sense.  However, my real concern is the precipitous drop in some key topic areas that are essential to building and working in the cloud computing.    &lt;/p&gt;

&lt;p&gt;My typical go to topic areas at re:Invent have been Architecture (23% decrease), Cloud Operations (43% decrease), Networking (107% decrease) and Storage (107% decrease).   The huge decreases in the areas of Customer Enablement and Hybrid Cloud are also alarming for folks who are coming to re:Invent for the first time and trying to figure out their cloud migration plans.&lt;/p&gt;

&lt;h2&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;Look, I get it, Generative AI is the new hotness, and AWS has to react to that given how often they are getting beat up for being "behind in AI."  However there needs to be balance, as a large number of folks who are building on AWS (including me) are not building anything that has to do with AI.   If we are going to spend $2000 and a week of our lives suffering through Las Vegas, our time needs to be rewarded with  a plethora of deep technical sessions on the topics that we care about.  &lt;/p&gt;

&lt;p&gt;Cloud Economist (and master of cloud snark) Corey Quinn had &lt;a href="https://www.lastweekinaws.com/blog/amazon-genai-services/" rel="noopener noreferrer" title=""&gt;a blog post reviewing the AWS New York &lt;/a&gt;summit earlier this year and I found this quote summed things up nicely:&lt;/p&gt;

&lt;blockquote&gt;

&lt;cite&gt;And so, the hyperfocus on GenAI is concerning to me because of what’s being shunted aside to create room for it. They’re Amazon &lt;strong&gt;WEB&lt;/strong&gt; Services, not Amazon GenAI Services. I &lt;a href="http://www.duckbillgroup.com/?__hstc=101025694.dea8a21e55ec566e2e862064ce81a349.1716411947419.1725401313204.1727978549226.4&amp;amp;__hssc=101025694.4.1727978549226&amp;amp;__hsfp=547971816" rel="noopener noreferrer"&gt;fix large AWS bills&lt;/a&gt; for large enterprises for a living; my customers have a raft of very large-scale challenges that don’t involve GenAI in the slightest. &lt;br&gt;                                                                                                                             - Corey Quinn&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;Will I be at re:Invent this year? Absolutely, for the reasons I outlined at the start of this post.  Will this be my last re:Invent? I'll let you know after December.&lt;/p&gt;

&lt;p&gt;What are your thoughts on the makeup of the re:Invent session catalog?  Am I overreacting?  Let me know in the comments.&lt;/p&gt;



</description>
      <category>aws</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Use IAM Roles Anywhere to reduce the use of IAM keys</title>
      <dc:creator>Mike Graff</dc:creator>
      <pubDate>Mon, 06 Nov 2023 00:34:17 +0000</pubDate>
      <link>https://dev.to/aws-builders/use-iam-roles-anywhere-to-reduce-the-use-of-iam-keys-53o7</link>
      <guid>https://dev.to/aws-builders/use-iam-roles-anywhere-to-reduce-the-use-of-iam-keys-53o7</guid>
      <description>&lt;h2&gt;Abstract&lt;/h2&gt;

&lt;p&gt;Exposed static IAM keys are one of the most common security risks for AWS accounts.  Avoiding the use of static keys is a best practice that can be hard to achieve in hybrid cloud environments where access needs to be given to external systems.   IAM Roles Anywhere is a service that help mitigate this risk.  In this article I detail the problems and risk associated with static keys, how IAM Roles Anywhere can solve this problem, and walk through how to setup the complete solution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
The Keys Problem&lt;ul&gt;
&lt;li&gt;Why this is bad&lt;/li&gt;
&lt;li&gt;The Toil of Managing Keys&lt;/li&gt;
&lt;li&gt;What about IAM Instance Roles?&lt;/li&gt;
&lt;li&gt;No Solution for External Systems&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;IAM Roles Anywhere Solves the Keys Problem&lt;/li&gt;
&lt;li&gt;
How does IAM Roles Anywhere Work?&lt;ul&gt;
&lt;li&gt;IAM Roles Anywhere Components&lt;/li&gt;
&lt;li&gt;IAM Roles Anywhere Architecture&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Setting Up IAM Roles Anywhere&lt;ul&gt;
&lt;li&gt;
Setup AWS Certificate Manager Private CA&lt;ul&gt;
&lt;li&gt;Steps to Setup the Root CA&lt;/li&gt;
&lt;li&gt;Important Note on CA Hierarchies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Configure IAM Roles Anywhere&lt;ul&gt;
&lt;li&gt;Establish Trust Anchor&lt;/li&gt;
&lt;li&gt;Configure Role&lt;/li&gt;
&lt;li&gt;Configure a Profile&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Configuring the External System&lt;ul&gt;
&lt;li&gt;Generate Client Certificate&lt;/li&gt;
&lt;li&gt;Export the Certificate&lt;/li&gt;
&lt;li&gt;Decrypt the Private Key&lt;/li&gt;
&lt;li&gt;Install IAM Credentials Helper&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Making the Connection&lt;ul&gt;
&lt;li&gt;Manually request and set credentials&lt;/li&gt;
&lt;li&gt;Leverage Roles Anywhere in AWS CLI Config&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Closing Thoughts&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="aioseo-the-keys-problem"&gt;The Keys Problem&lt;/h2&gt;

&lt;p&gt;One of the more pesky problems to solve when managing an AWS environment is granting access to external systems in a secure manner.   External access to the AWS console can be handled via username and password (or even better, leverage SSO login via IAM Identity Center!).  Unfortunately, this method doesn't work for API access from machines and applications outside your AWS environment.&lt;/p&gt;

&lt;h4 id="aioseo-why-this-is-bad"&gt;Why this is bad&lt;/h4&gt;

&lt;p&gt;The most common solution for providing external access is not awesome.  You generate an IAM access key pair for the application or system and pass those credentials over to your developer for use.  Afterwords, you keep your fingers crossed that they do not share these keys with other folks or store them in plain text on their computer.  Even worse would be if they put these credentials directly into their code and then commit it to a git repo.   &lt;/p&gt;

&lt;p&gt;Without a doubt this last scenario happens all the time, and consequently it is something that hackers are constantly scanning GitHub repos to find and exploit to get access to your AWS accounts.&lt;/p&gt;

&lt;h4 id="aioseo-the-toil-of-managing-keys"&gt;The Toil of Managing Keys&lt;/h4&gt;

&lt;p&gt;Let's say you are able to avoid these credentials getting exposed accidentally.  You still have to make sure you are performing good security practices on these keys by rotating them regularly.  For example, in my environment we rotate keys every 75 days.  Then you have to go through the process of securely exchanging the keys with your developers again, and they have to update their application to use the new keys.  Wash, rinse, and repeat this process every few months and that adds up to a lot of toil just to keep your keys secure.&lt;/p&gt;

&lt;h4 id="aioseo-no-solution-for-external-systems"&gt;What about IAM Instance Roles?&lt;/h4&gt;

&lt;p&gt;This problem has been solved for years for systems running &lt;strong&gt;inside&lt;/strong&gt; of AWS with &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html" rel="noopener" title=""&gt;IAM Instance Roles&lt;/a&gt;.  This feature allows you to assign an IAM Role directly to an EC2 instance (or container or Lambda function).  As a result, the EC2 instance then dynamically retrieves an access token for the role via the EC2 Instance Metadata service.  Very slick and no static keys required! &lt;/p&gt;

&lt;h4 id="aioseo-no-solution-for-external-systems"&gt;No Solution for External Systems&lt;/h4&gt;

&lt;p&gt;However, the very nature of the way this service works requires that the calling system be inside AWS.   For external systems you had no option beyond static keys.  Thankfully, that all changed in July 2022 when AWS announced &lt;a href="https://aws.amazon.com/blogs/security/extend-aws-iam-roles-to-workloads-outside-of-aws-with-iam-roles-anywhere/" rel="noopener" title=""&gt;IAM Roles Anywhere&lt;/a&gt;.  &lt;/p&gt;

&lt;h2 id="aioseo-what-is-iam-roles-anywhere-and-how-does-it-work"&gt;IAM Roles Anywhere Solves the Keys Problem&lt;/h2&gt;

&lt;p&gt;IAM Roles Anywhere makes it possible to use IAM Roles on systems outside of AWS.  It provides a mechanism for external servers, containers, and applications to obtain temporary AWS credentials in a manner similar to EC2 Instance Roles.   Thus it eliminates the need to create and manage static access keys and dramatically improves the security posture of your AWS accounts.&lt;/p&gt;

&lt;h2 id="aioseo-how-does-iam-roles-anywhere-work"&gt;How does IAM Roles Anywhere Work?&lt;/h2&gt;

&lt;p&gt;IAM Roles Anywhere leverages public key infrastructure (PKI) as a mechanism to establish trust between your external system and your AWS Account.   Systems sitting outside of AWS hold X.509 Certificates that they present as part of a CreateSession request.   Next these certificates are validated by IAM Roles Anywhere and then a temporary set of credentials are returned to the client. &lt;/p&gt;

&lt;h3 id="aioseo-iam-roles-anywhere-components"&gt;IAM Roles Anywhere Components&lt;/h3&gt;

&lt;p&gt;There are six basic components to the IAM Roles Anywhere architecture.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Certificate_authority" title=""&gt;Certificate Authority (CA)&lt;/a&gt;&lt;/strong&gt;.  The CA is the heart of your public key infrastructure and is responsible for issuing certificates.  For IAM Roles Anywhere you can use a CA provided by Amazon Certificate Manager, or you can &lt;a href="https://aws.amazon.com/blogs/security/iam-roles-anywhere-with-an-external-certificate-authority/" rel="noopener" title=""&gt;use an existing External CA&lt;/a&gt;.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/X.509" rel="noopener" title=""&gt;Certificates&lt;/a&gt;&lt;/strong&gt; are digital documents that securely associate cryptographic key pairs with a system.  A certificate contains the public key and a signature that has been encrypted with the private key.  This allows a third party to verify that a certificate is valid by decrypting the signature using the public key.  Certificates also contain a trust chain that links the certificate back to the CA that issued it.  &lt;/li&gt;



&lt;li&gt;A &lt;strong&gt;Trust Anchor&lt;/strong&gt; is used to establish a trust relationship between IAM Roles Anywhere and your Certificate Authority.&lt;/li&gt;



&lt;li&gt;An &lt;strong&gt;IAM Role&lt;/strong&gt;. You probably already know that a &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html" rel="noopener" title=""&gt;Role&lt;/a&gt; is an IAM identity that contains specific permissions you wish to grant and that can be assumed by anyone who needs it.   In order to use a role with IAM Roles Anywhere, your role must be configured to trust the IAM Roles Anywhere service principal.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Profiles&lt;/strong&gt; are used to specify which roles IAM Roles Anywhere can assume and what your workloads can do with the temporary credentials that are issued.  You can specify a session policy to limit the permissions created for the session.&lt;/li&gt;



&lt;li&gt;Lastly, the &lt;strong&gt;&lt;a href="https://docs.aws.amazon.com/rolesanywhere/latest/userguide/credential-helper.html" rel="noopener" title=""&gt;IAM Roles Credential Helper&lt;/a&gt;&lt;/strong&gt; is a downloadable tool provided by AWS that allows you to request temporary security credentials via the CreateSession API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="aioseo-iam-roles-anywhere-architecture"&gt;IAM Roles Anywhere Architecture&lt;/h3&gt;

&lt;p&gt;Here is a diagram that illustrates the components of the IAM Roles Architecture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fm3Wi4WR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/IAM-Roles-Anywhere-Architecture-3-1024x575.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fm3Wi4WR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/IAM-Roles-Anywhere-Architecture-3-1024x575.png" alt="A an architecture diagram showing the IAM Roles Anywhere solution components and their relationships" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The components of the architecture work together in the following way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Trust Anchor is established between IAM Roles Anywhere and the Certificate Authority (CA).  This CA can be running inside of AWS or externally in your own data center or even another cloud provider.&lt;/li&gt;



&lt;li&gt;The CA issues an x.509 Certificate to the external system, where it is installed in the local store.&lt;/li&gt;



&lt;li&gt;The IAM Role is created and configured to trust the IAM Roles Anywhere service principal.&lt;/li&gt;



&lt;li&gt;A Roles Anywhere Profile associates the IAM Role with Roles Anywhere and can set session restrictions if desired.&lt;/li&gt;



&lt;li&gt;The External Server issues a CreateSession request and provides it's Certificate along with specifying the role it wishes to assume.&lt;/li&gt;



&lt;li&gt;IAM Roles Anywhere validates the Certificate is valid and tied to the CA contained in the trust anchor.&lt;/li&gt;



&lt;li&gt;Once these validations are complete, the system is now authenticated and IAM Roles Anywhere will create a role session via STS and pass the session credentials back to the external system.&lt;/li&gt;



&lt;li&gt;The external system can now use these temporary credentials to make any AWS API calls that are allowed in the IAM Role.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="aioseo-setting-it-up"&gt;Setting Up IAM Roles Anywhere&lt;/h2&gt;

&lt;p&gt;Now that I've gone over the basic architecture of IAM Roles Anywhere, next I'm going to walk you through an end to end deployment of this solution.  For my lab deployment I will use AWS Certificate Manager Private CA as our Certificate Authority.   As a result the first thing I will walk through is how to stand up the Private CA.&lt;/p&gt;

&lt;h3 id="aioseo-setup-aws-certificate-manager-private-ca"&gt;Setup AWS Certificate Manager Private CA&lt;/h3&gt;

&lt;p&gt;AWS Certificate Manager is AWS' fully managed Certificate Authority service.   You are probably most familiar with this service as a method for issuing public certificates for use with other services like CloudFront and API Gateway, but the service also has the capability to act as a &lt;a href="https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html" rel="noopener" title=""&gt;Private CA&lt;/a&gt;, allowing you to setup entire managed CA hierarchies without the headache of managing your own CA (and trust me, having setup my own private PKI hierarchies in the past, it neither fun to setup nor maintain).  &lt;/p&gt;

&lt;h4 id="aioseo-steps-to-setup-the-root-ca"&gt;Steps to Setup the Root CA&lt;/h4&gt;

&lt;p&gt;First, we need to setup the Root CA&lt;/p&gt;

&lt;p&gt;To get started, login to your AWS account with the appropriate credentials and navigate to the &lt;strong&gt;Certificate Manager&lt;/strong&gt; service. From the Certificate Manager home page, click the link for &lt;strong&gt;AWS Private CA&lt;/strong&gt; on the left hand navigation bar&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wo0WClhg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/certificate-manager-launch-private-CA-2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wo0WClhg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/certificate-manager-launch-private-CA-2.jpg" alt="AWS Certificate Manager home page with link to AWS Private Certificate Authority " width="778" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the resulting page, click the orange &lt;strong&gt;Create a Private CA&lt;/strong&gt; button to get started creating your new Private CA.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w8Iuwqim--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/Create_a_Private_CA_button.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w8Iuwqim--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/Create_a_Private_CA_button.jpg" alt="AWS Private Certificate Authority Create a Private CA button" width="800" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_yRB_HU0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-root-ca-part1-531x1024.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_yRB_HU0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-root-ca-part1-531x1024.jpg" alt="AWS Private Certificate Authority Create a Certificate Authority Wizard with CA Type, Subject DN and Key Algorithm settings." width="531" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After clicking the button, you will be presented with the &lt;strong&gt;Create a private certificate authority&lt;/strong&gt; wizard page.  Here we will be configuring all the required options to stand up our private Certificate Authority.    &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For your CA Mode options, select &lt;strong&gt;General Purpose&lt;/strong&gt;.  NOTE: if you are following along and setting this up in a lab environment be aware of &lt;a href="https://aws.amazon.com/private-ca/pricing/" rel="noopener" title=""&gt;Amazon Private CA pricing&lt;/a&gt;.   A General Purpose private CA will cost you $400/month!  I have not tested the option to use the short-lived certificate mode, and it certainly would not work for a production deployment as the certificates would expire too quickly. &lt;/li&gt;



&lt;li&gt;For CA type, select &lt;strong&gt;Root&lt;/strong&gt;
&lt;/li&gt;



&lt;li&gt;Fill in your Subject DN options as you please with Organization, Organization Unit, Country, State, Locality and Common Name.&lt;/li&gt;



&lt;li&gt;Set your key algorithm as desired, e.g. RSA 2048&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--llxqbsoS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-root-ca-part2-635x1024.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--llxqbsoS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-root-ca-part2-635x1024.jpg" alt="AWS Private Certificate Authority Create a Certificate Authority Wizard with CRL options." width="635" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next we need to setup a Certificate Revocation List distribution point so we can have a place to publish certificates that are no longer valid.   All properly configured CAs must have a CRL location for the CA to be trusted.&lt;/li&gt;



&lt;li&gt;Check the boxes for &lt;strong&gt;Activate CRL Distribution&lt;/strong&gt; and &lt;strong&gt;Create a new S3 bucket&lt;/strong&gt;.   &lt;/li&gt;



&lt;li&gt;Enter a new bucket name in the S3 bucket name field.  &lt;/li&gt;



&lt;li&gt;You can leave the other CRL settings as default.  &lt;/li&gt;



&lt;li&gt;Add tags as desired&lt;/li&gt;



&lt;li&gt;Under CA permissions options, ensure that the check box for &lt;strong&gt;Authorize ACM access to renew certificates&lt;/strong&gt; is checked.  &lt;/li&gt;



&lt;li&gt;Finally, check the box acknowledging the pricing for ACM and click the &lt;strong&gt;Create CA&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our Root CA is now created, but to finish activating it we need to Install a CA Certificate.  From the Actions menu in the top right corner of the Certificate Authority homepage, you should choose &lt;strong&gt;Install CA Certificate&lt;/strong&gt;.  On the resulting screen accept the default 10 year validity period and SHA256 signing algorithm and click the &lt;strong&gt;Confirm and install&lt;/strong&gt; button.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nnuKwl-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/install-root-certificate.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nnuKwl-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/install-root-certificate.jpg" alt="The AWS Private CA Install Root CA Certificate Wizard with Validity and Signature Algorithm settings." width="711" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After completing these steps, you now have a functioning Root CA that is able to start issuing private certificates.  &lt;/p&gt;

&lt;h4 id="aioseo-important-note"&gt;Important Note on CA Hierarchies&lt;/h4&gt;

&lt;p&gt;From a PKI best practices perspective, you normally would never issue client certificates from your Root CA.  Instead you would setup a subordinate "Issuing CA" that trusts the Root CA and that would be used to issue all your client certificates.  However in the interest of simplifying this blog post and avoiding the additional cost of running multiple CAs, I'm going to skip that step here and move on to configuring IAM Roles Anywhere.  Just be aware of this for your production Certificate Authority deployment.&lt;/p&gt;

&lt;h3 id="aioseo-configure-iam-roles-anywhere"&gt;Configure IAM Roles Anywhere&lt;/h3&gt;

&lt;p&gt;Now that we have a functioning Certificate Authority, let's get into setting up IAM Roles Anywhere.  To get started with this task, navigate to the IAM service page in your AWS Console.  Next, click on &lt;strong&gt;Roles&lt;/strong&gt; on the left side navigation bar. At the bottom of the resulting page you will see a section for &lt;strong&gt;Roles Anywhere&lt;/strong&gt;.  Click the &lt;strong&gt;Manage&lt;/strong&gt; button to get started setting it up.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l3bWaZlp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/manage-roles-anywhere-1024x299.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l3bWaZlp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/manage-roles-anywhere-1024x299.jpg" alt="AWS IAM Roles console showing the Manage Roles Anywhere button." width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id="aioseo-establish-trust-anchor"&gt;Establish Trust Anchor&lt;/h4&gt;

&lt;p&gt;The Roles Anywhere page has a very nice Setup wizard that will walk you through the process.   The first thing we need to do is create a &lt;strong&gt;trust anchor&lt;/strong&gt; to the Private CA we setup in the previous step.  Click the orange &lt;strong&gt;Create a trust anchor&lt;/strong&gt; button to get started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iZjNcpMo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-a-trust-anchor-1024x437.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iZjNcpMo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-a-trust-anchor-1024x437.jpg" alt="Manage IAM Roles Anywhere console showing the Step 1: Establish Trust and highlighting the Create a trust anchor button" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be taken to the &lt;strong&gt;Create a trust anchor&lt;/strong&gt; wizard page.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, enter a friendly name for your trust anchor.&lt;/li&gt;



&lt;li&gt;Next you will choose your CA source.  Here is where you can specify an external CA to trust via uploading a certificate bundle, or you can go with &lt;strong&gt;AWS Private Certificate Authority&lt;/strong&gt;, which is the default option.&lt;/li&gt;



&lt;li&gt;Below in the next section you will see a list of AWS Private Certificate Authorities in the account. Click the radio button next to the root CA we created in the previous step.  &lt;/li&gt;



&lt;li&gt;Leave notification options as default and add tags as appropriate.&lt;/li&gt;



&lt;li&gt;Finally, click the orange &lt;strong&gt;Create a trust anchor button&lt;/strong&gt; to complete the process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L53q46fz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-trust-anchor-wizard-1-689x1024.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L53q46fz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-trust-anchor-wizard-1-689x1024.jpg" alt="Screenshot of the IAM Roles Anywhere Create a trust anchor wizard" width="689" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id="aioseo-configure-role"&gt;Configure Role&lt;/h4&gt;

&lt;p&gt;After you create your trust anchor, the Setup wizard will move to the next step, &lt;strong&gt;Configuring roles&lt;/strong&gt;.  If you have an existing role, you can easily configure it for Roles Anywhere by adding the required trust statements to the role.   For our demo, let's make things simple and create a new role for use with Roles Anywhere.  You can do this by clicking the &lt;strong&gt;Create a new role button.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9hVgx61B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/roles-anywhere-create-a-new-role.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9hVgx61B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/roles-anywhere-create-a-new-role.jpg" alt="Screenshot of the Manage IAM Roles Anywhere service highlighting the button to Create a new role." width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking that button will take you directly to the IAM Role creation wizard.   Step 1 is &lt;strong&gt;Select trusted entity&lt;/strong&gt;.   &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the button next to &lt;strong&gt;AWS Service&lt;/strong&gt;.  &lt;/li&gt;



&lt;li&gt;From the Use case drop down menu, select &lt;strong&gt;Roles Anywhere&lt;/strong&gt;.&lt;/li&gt;



&lt;li&gt;Click &lt;strong&gt;Next&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jONfsyPS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-role-select-trust.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jONfsyPS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-role-select-trust.jpg" alt="Screenshot of the IAM Role creation wizard Select Trusted Entity step." width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EisuSt15--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/assign-permissions-to-role.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EisuSt15--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/assign-permissions-to-role.jpg" alt="Screenshot of the IAM Role creation wizard Add Permissions step." width="800" height="753"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here we need to add permissions to the role.  This will control what API actions the external system is able to use via Roles Anywhere.   &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can attach any existing IAM policy in your account, AWS Managed policies, and even attach multiple policies.  &lt;/li&gt;



&lt;li&gt;For this demonstration I'm going to grant the &lt;strong&gt;AmazonS3ReadOnlyAccess&lt;/strong&gt; managed policy and click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To complete the wizard, give your new Role a name and description, review the trust policy and permissions you just setup, assign tags and then click the orange &lt;strong&gt;Create Role&lt;/strong&gt; button.&lt;/p&gt;

&lt;h4 id="aioseo-configure-a-profile"&gt;Configure a Profile&lt;/h4&gt;

&lt;p&gt;After you role is created, navigate back to the &lt;strong&gt;Manage Roles Anywhere&lt;/strong&gt; screen. The final setup step is to create a &lt;strong&gt;Profile&lt;/strong&gt; that will associated your IAM Role for use with Roles Anywhere using a role session policy.   To complete this step, click the button that says &lt;strong&gt;Configure a Profile&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P6HcwTzi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/roles-anywhere-configure-profile.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P6HcwTzi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/roles-anywhere-configure-profile.jpg" alt="Screenshot of the Manage IAM Roles Anywhere service highlighting the button to Configure a Profile." width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Time for yet another wizard page!  Here you will complete the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give your Profile a name&lt;/li&gt;



&lt;li&gt;In the &lt;strong&gt;Roles&lt;/strong&gt; section, chose the role we created in the previous step&lt;/li&gt;



&lt;li&gt;In the &lt;strong&gt;Session Policies&lt;/strong&gt; section, you can optionally limit what permissions are granted by the role for the session created via Roles Anywhere.  For our case we will remove the default inline policy that is present, as it grants ALL access.&lt;/li&gt;



&lt;li&gt;Apply Tags&lt;/li&gt;



&lt;li&gt;Finally click the &lt;strong&gt;Create a profile&lt;/strong&gt; button to finish the wizard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--27kjAZvI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-profile-wizard-719x1024.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--27kjAZvI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/create-profile-wizard-719x1024.jpg" alt="Screenshot of the IAM Roles Anywhere service Create a profile wizard." width="719" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point we have successfully completed all the setup tasks to get our IAM Roles Anywhere backend configured.   &lt;/p&gt;

&lt;h2 id="aioseo-configuring-the-external-system"&gt;Configuring the External System&lt;/h2&gt;

&lt;p&gt;With our Roles Anywhere backend up and running, let's move on to configuring the external system for access.   The first step for this is to issue an x.509 certificate for our external system to use for authenticating to IAM Roles Anywhere.&lt;/p&gt;

&lt;h3 id="aioseo-generate-client-certificate"&gt;Generate Client Certificate&lt;/h3&gt;

&lt;p&gt;In the AWS console, navigate back to &lt;strong&gt;Amazon Certificate Manager&lt;/strong&gt; service.  From the service home page, click &lt;strong&gt;Request Certificate&lt;/strong&gt; on the left side navigation bar (or click the big red orange button on the right):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C1-j6Yap--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/request-certificate-1024x321.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C1-j6Yap--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/request-certificate-1024x321.jpg" alt="Amazon Certificate Manager home page highlighting the button to request a new Certificate" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under Certificate type, choose the option &lt;strong&gt;Request a private certificate&lt;/strong&gt; and click &lt;strong&gt;Next&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LM3qsmfy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/request-a-private-cert.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LM3qsmfy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/request-a-private-cert.jpg" alt="Amazon Certificate Manager Request a new Certificate feature showing the choices for certificate type of public or private." width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You guessed it, it's wizard time!  From this wizard we will be completing the required properties for our certificate request (CSR).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;strong&gt;Certificate Authority&lt;/strong&gt; drop down menu, select the private CA we created earlier.&lt;/li&gt;



&lt;li&gt;Enter your domain name for the certificate in the &lt;strong&gt;Domain Name&lt;/strong&gt; section.&lt;/li&gt;



&lt;li&gt;Choose your K&lt;strong&gt;ey algorithm&lt;/strong&gt;. In this case I'm going with the default of RSA 2048.&lt;/li&gt;



&lt;li&gt;Add tags as desired.&lt;/li&gt;



&lt;li&gt;Under &lt;strong&gt;Certificate Renewal Permissions&lt;/strong&gt;, click the box to acknowledge that ACM will need permissions to rewew this cert.  (you may remember we already granted this permission when we setup the CA originally).&lt;/li&gt;



&lt;li&gt;Click the orange &lt;strong&gt;Request&lt;/strong&gt; button to complete the request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BeUljTKD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/private-csr-668x1024.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BeUljTKD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/private-csr-668x1024.jpg" alt="Request a private certificate wizard screen" width="668" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id="aioseo-export-the-certificate"&gt;Export the Certificate&lt;/h3&gt;

&lt;p&gt;Your certificate will get created and after a few moments the certificate status should update from &lt;strong&gt;Pending validation&lt;/strong&gt; to &lt;strong&gt;Issued&lt;/strong&gt; in the Certificates list.  Once the certificate is issued, we need to download it so we can place it on our external system.  Click on the certificate in the list and from the details page click the &lt;strong&gt;Export&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pIkSsGv4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/export-cert-button-1-1024x226.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pIkSsGv4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/export-cert-button-1-1024x226.jpg" alt="AWS Certificate Manager Certificate Details screen with the Export button highlighted." width="800" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the Export Certificate page you will need to add a passphrase so that the private key can be encrypted.  Next, click the checkbox to acknowledge that you will be charged for exporting this certificate:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LBshSwlx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/export-cert-wizard.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LBshSwlx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cloudyadvice.com/wp-content/uploads/2023/11/export-cert-wizard.jpg" alt="AWS Certificate Manager console showing the Export a certificate request form." width="787" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you click &lt;strong&gt;Generate PEM encoding&lt;/strong&gt;, the service will return to you three items, each with Download links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Certificate body&lt;/li&gt;



&lt;li&gt;Certificate chain&lt;/li&gt;



&lt;li&gt;Certificate private key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you will need to download each of these to your local system.  You can do this by either clicking the download buttons for each item, or creating text files on your local system and copying the text into them.  Place all these files in a folder on your system.  After downloading the files, you will need to rename certificate.txt to &lt;strong&gt;certificate.pem&lt;/strong&gt; and private_key.txt to &lt;strong&gt;private_key.pem&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id="aioseo-decrypt-the-private-key"&gt;Decrypt the Private Key&lt;/h3&gt;

&lt;p&gt;Once the files are downloaded, next we need to decrypt the private key using the passphrase we entered when we performed the export.  On a Mac or Linux system we can do that easily with openssl.  Here is  the command to use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;openssl rsa -in private_key.pem -out decrypted_private_key.pem &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Openssl will run and prompt you to enter the passphrase you created, and then decrypt the key to the designated output file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Enter pass phrase for private_key.pem:
writing RSA key&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Success!  We've now created a new certificate for our system in Amazon Private CA, exported it our system have it ready for use with the IAM Roles Credential Helper.&lt;/p&gt;

&lt;h3 id="aioseo-install-iam-credentials-helper"&gt;Install IAM Credentials Helper &lt;/h3&gt;

&lt;p&gt;As mentioned before the IAM Roles Credentials Helper is a downloadable tool maintained by AWS.   The tool is used to create a SigV4 signature with your certificate and make a call to the Roles Anywhere endpoint to obtain session credentials.   Next, the Roles Anywhere endpoint then returns the credentials to the calling process in JSON format.   You can download the latest version of the tool from the &lt;a href="http://s%20a%20downloadable%20tool%20provided%20by%20AWS%20that%20allows%20you%20to%20request%20temporary%20security%20credentials%20via%20the%20CreateSession%20API" rel="noopener" title=""&gt;IAM Roles Anywhere User Guide&lt;/a&gt;, where there are packages for Linux, Windows, and Darwin (MacOS). Download the helper and place it in the same directory where you placed your certificate and private key.  First, you'll need to make the package executable before you can use it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;chmod +x aws_signing_helper&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this last step done, we've completed all the end to end setup work needed to use Roles Anywhere.   To wrap up the article, I'm going to demonstrate how to make a CreateSession API request using the credentials helper.&lt;/p&gt;

&lt;h2 id="aioseo-making-the-connection"&gt;Making the Connection&lt;/h2&gt;

&lt;p&gt;There are three things we will need to have in order to use the AWS IAM Roles Anywhere Credentials Helper to make a CreateSession request.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Roles Anywhere Trust Anchor Amazon Resource Name (ARN)&lt;/li&gt;



&lt;li&gt;Profile ARN&lt;/li&gt;



&lt;li&gt;IAM Role ARN&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first two items can be obtained from the IAM Roles Anywhere management page, while the IAM Role ARN can be found by examining the details of the Role in the IAM Roles page.  You will also need the filenames for your certificate and decrypted private key that we downloaded in the previous step.&lt;/p&gt;

&lt;h3 id="aioseo-manually-request-and-set-credentials"&gt;Manually request and set credentials&lt;/h3&gt;

&lt;p&gt;You will combine all these items as the options for our rather long &lt;strong&gt;aws_signing_helper &lt;/strong&gt;command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./aws_signing_helper credential-process \
--trust-anchor-arn arn:aws:rolesanywhere:us-east-1:&lt;em&gt;111111111111&lt;/em&gt;:trust-anchor/49d455a6-deec-4cfc-9c12-2c75217ea49a --profile-arn arn:aws:rolesanywhere:us-east-1:&lt;em&gt;111111111111&lt;/em&gt;:profile/d0119c28-ecfa-4ad2-88c7-cacfd61bb268 \
--role-arn arn:aws:iam::&lt;em&gt;111111111111&lt;/em&gt;:role/cloudyadvice-roles-anywhere-role \
--certificate certificate.pem --private-key decrypted_private_key.pem&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note I've modified the account numbers here, you should replace with the proper values from your ARNs.  If all goes well, AWS will return you an Access Key ID, Secret Access Key, and Session token in JSON format, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{"Version":1,"AccessKeyId":"ASIAVFPLXXXXXXXXXXXX","SecretAccessKey":"+ZCVCbiRHXwCOBZCi0JVv/XXXXXXXXXXXXX","SessionToken":"IQoJb3JpZ2luX2VjEC4aCXVzLWVhc3QtMSJGMEQCIFgE1/1OZjanZDOiMnVkxgKMXsoZVlQl3QJy2POXadb/AiAm7EqPHvXslugCqcaS6wCtquf/XIaMTg1YbJg3ywfXDCqIBAhmEAIaDDM1NTM2NDgyOTg2NCIM0BYAV8uBV1afYXAuKuUDMXS8VhT4SnBqg+S4yqtOj0TSZdbp/z4AKJeovB6u9g/5f2SA1tAG3hkByq/PEiuLFGN0kIgkWT66CPDNHS5iuPVXhiHIghaNqVDXzGXvWcxp5SPLbIIAQxfyQTmNiBhqg82VDaEUEutSh2kd8CdvTtlP39tEFE0q8poWbNCnDCwg1Wj50LaH7IQb3jYoTxHAnHEkTmtlqmoeYIM7UVc1RQ2Fox37nnMZVqaeY0tCyxyfmQn8tCEmaFRTxYWweCfxB7WIjptGwQGUchEBbISHnJulKU9Pv8lgct3HENWqyQcVKSWRZDvIAuFjpfq8cahcAVHrzM20KNMO3OxfZyXhBgSNalxO6c0pGoBDgmlH1o8yEVky2GSzYncSwyL++KPAzb/+FeNiT4aJeSyd3ns0Ewp/s30JbC8fuID6UuuuSfNa7VetSFBanSfIkjDhUnefjyYFyz2f+7k2X5HPYeAmT/zjwOGpNY7KcIJqZQHERhaMWn5Gy0RvjvAoVVAgyEwqwBff76TEwmxh6DMN4o/LRuOnflommJojT0BmVtfBD5Ykp53xZXPCQctF7ijN40Ud18w8ZIBF/6QUAdQe1Lp32kIH9HPq3Lg4YlvJzdsMX6BXemDWHCFLCE1BfFQXXBRRs0p8Ci8wgueaqgY6lAHD/crexcd3uBsB87czp6kyYV8iH4BMPPpxbIs3fAgjOkJMta2pROF72YKR9FRF9ixciFkBCpnACjWGSDSuwx/+elwoDJ3zlCOad7SYX0J8CBxAKKAQ564MOiYrB9wdf3N2sQd+dKJkmPSZxEN1sWnMnD/D+HrWB7A0ULsW3phER50gisns8G/KsE4q4gtz1QOrOIP6","Expiration":"2023-11-04T22:11:30Z"}% &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, Roles Anywhere has sent you back a send of temporary credentials in the form of an Access Key ID, a Secret Access Key, and a Session Token.   You can simply use these values returned here to set as temporary environment variables for your AWS credentials, and then issue calls to AWS using those environment variables.   For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export AWS_ACCESS_KEY_ID=&lt;em&gt;access-key-id-value&lt;/em&gt;
export AWS_SECRET_ACCESS_KEY=&lt;em&gt;secret-access-key-value&lt;/em&gt;
export AWS_SESSION_TOKEN=&lt;em&gt;session-token-value&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once that is done you can issue AWS CLI commands, e.g. get a list of S3 buckets:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;aws s3api list-buckets&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which should return you a list of S3 buckets in JSON format.&lt;/p&gt;

&lt;h3 id="aioseo-leverage-roles-anywhere-in-aws-cli-config"&gt;Leverage Roles Anywhere in AWS CLI Config&lt;/h3&gt;

&lt;p&gt;Manually requesting credentials is a great way to test, but rather laborious to do on a regular basis.  Fortunately you can leverage the &lt;strong&gt;aws_signing_helper&lt;/strong&gt; as a custom credential_process for the AWS CLI.  To do this, you simply need to add it as a new profile entry in your AWS CLI credentials file to invoke it.   First, copy the certificate files and the aws_signing_helper executable to the same directory where your AWS CLI is located, typically ~./aws.   Next, you add a new profile to your ~/.aws/config file that leverages IAM Roles Anywhere.   The profile entry should look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;strong&gt;[profile rolesanywhere]&lt;/strong&gt;
credential_process = /users/cloudyadvice/.aws/aws_signing_helper credential-process --trust-anchor-arn arn:aws:rolesanywhere:us-east-1:&lt;em&gt;111111111111&lt;/em&gt;:trust-anchor/49d455a6-deec-4cfc-9c12-2c75217ea49a --profile-arn arn:aws:rolesanywhere:us-east-1:&lt;em&gt;111111111111&lt;/em&gt;:profile/d0119c28-ecfa-4ad2-88c7-cacfd61bb268 \
--role-arn arn:aws:iam::&lt;em&gt;111111111111&lt;/em&gt;:role/cloudyadvice-roles-anywhere-role \
--certificate certificate.pem --private-key decrypted_private_key.pem&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Obviously, you would need to replace the dummy values shown here with the proper values from your own environment.  Once you've added this new profile to your ~/.aws/config file, you can call it for use with any AWS CLI command with the --profile flag, for example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;aws s3 ls --profile rolesanywhere&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now AWS CLI will leverage Roles Anywhere to mint dynamic temporary credentials when you execute commands using this profile switch.  Totally awesome!!&lt;/p&gt;

&lt;h2 id="aioseo-closing-thoughts"&gt;Closing Thoughts&lt;/h2&gt;

&lt;p&gt;I was so excited when IAM Roles Anywhere was announced because it solves a real world problem I often have to deal with in my day job.  As a result I was glad to finally got around to testing it out and writing up this blog post. &lt;/p&gt;

&lt;p&gt;Obviously, this was a fairly long blog post covering a pretty complicated setup. AWS IAM by itself is a very complicated service.  Then when you add public key infrastructure into the mix, things get even more complicated.  To help with this complexity, I've done my best here to walk through the steps in an easy to follow fashion so you can start experimenting with this powerful service.&lt;/p&gt;

&lt;p&gt;I hope that you will see the benefit of this great service and use it to make your own AWS environments more secure.   Are you already using IAM Roles Anywhere in your environment?  Share your experiences and thoughts in the comments!&lt;/p&gt;

&lt;h2 id="aioseo-references"&gt;References&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/security/extend-aws-iam-roles-to-workloads-outside-of-aws-with-iam-roles-anywhere/" rel="noopener" title=""&gt;AWS Security Blog - IAM Roles Anywhere Launch Post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/security/iam-roles-anywhere-with-an-external-certificate-authority/"&gt;AWS Security Blog - IAM Roles Anywhere with an external certificate authority&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/security/enable-external-pipeline-deployments-to-aws-cloud-by-using-iam-roles-anywhere/" rel="noopener" title=""&gt;AWS Security Blog - Enable external pipeline deployments to AWS Cloud by using IAM Roles Anywhere&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/rolesanywhere/latest/userguide/introduction.html" rel="noopener" title=""&gt;AWS IAM Roles Anywhere User Guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/gOXILJcOemo?si=uuEwrtTJbMlPI3Xo" rel="noopener" title=""&gt;YouTube - AWS re:Inforce 2023 Managing hybrid workloads with IAM Roles Anywhere, featuring Hert&lt;/a&gt;z&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/n4UZZsTIlVA?si=UnvO6xLFzJvckjru" rel="noopener" title=""&gt;Hacker Loi YouTube - AWS IAM Roles Anywhere Full Tutorial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/aws/rolesanywhere-credential-helper" rel="noopener" title=""&gt;GitHub AWS repo - roles anywhere credential helper&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>iam</category>
      <category>cloud</category>
      <category>security</category>
    </item>
    <item>
      <title>Build Easy Chargeback Reports using AWS Cost Categories</title>
      <dc:creator>Mike Graff</dc:creator>
      <pubDate>Thu, 06 Oct 2022 15:08:09 +0000</pubDate>
      <link>https://dev.to/michaelegraff/build-easy-chargeback-reports-using-aws-cost-categories-2945</link>
      <guid>https://dev.to/michaelegraff/build-easy-chargeback-reports-using-aws-cost-categories-2945</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;At my day job, we first started using public cloud back in 2015, and at the time we were really just starting to crawl with cloud financials.   Our finance department was not a fan of chargeback and as a result we ended up partnering with a third party reseller to help us with our cloud billing.    We built a complicated system where we leveraged the reseller for consolidated billing, and each business team would issue a separate PO to the reseller for their AWS usage.  The reseller was using a commercial tool called CloudHealth to slice and dice our bill and generate 70+ invoices each month back to us for each team.&lt;/p&gt;

&lt;p&gt;Fast forward to the second half of 2021, and at this point our increased maturity around managing public cloud meant that it was time to start walking on our own and bring the cloud billing in-house.  In April 2022 I wrapped up a six month project that had three main objectives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Develop and implement new internal tools to replace the capabilities of CloudHealth&lt;/li&gt;
&lt;li&gt;Design and implement a new cost allocation scheme for our AWS and GCP bills&lt;/li&gt;
&lt;li&gt;Negotiate a new EDP with AWS and migrate away from the third party reseller.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result?   A lot less paperwork in the form of purchase orders, invoices, and payments, more transparency on AWS costs for our account holders, and stronger FinOps muscles for our team.&lt;/p&gt;

&lt;p&gt;Part of my solution was to implement the CUDOS Cost Intelligence Dashboards to replace the reporting capabilities of CloudHealth. You can also read about how I implemented CUDOS for my enterprise by reading these earlier blog posts:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cloudyadvice.com/2022/04/29/implementing-cudos-cost-intelligence-dashboards-for-an-enterprise/"&gt;Implementing CUDOS for the Enterprise – Part 1&lt;/a&gt;&lt;br&gt;
&lt;a href="https://cloudyadvice.com/2022/05/18/implementing-cudos-row-level-security/"&gt;Implementing CUDOS for the Enterprise – Part 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, I’m going to talk about our solution for creating a chargeback report for allocating our AWS spend back to business groups. I will provide a deep dive into the AWS Cost Categories tool, which we are using for cost allocation.  I’ll talk about how it works, how we are using it at my company, and some of the lessons learned along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS Cost Categories
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GcT5Cf9m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/ac71ol273n973wnyhlmv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GcT5Cf9m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/ac71ol273n973wnyhlmv.png" alt="Cost Categories Home Page" width="880" height="455"&gt;&lt;/a&gt;&lt;br&gt;
AWS Cost Categories is a feature within AWS’ Cost Management suite that allows you to group cost and usage information into meaningful categories based on your needs.   &lt;/p&gt;

&lt;p&gt;You can map AWS charges in whatever way makes the most sense for your business, for example business units, environments, product lines, etc.  In our case, we were primarily looking to catagorize charges based on internal cost centers defined by our Finance group.   &lt;/p&gt;

&lt;p&gt;After you create these cost categories, they become part of the Cost and Usage Report and are thus available for use in other parts of the Cost Management suite like Cost Explorer, AWS Budgets and my personal favorite the CUDOS Cost Intelligence dashboards. &lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;So how to get started? &lt;/p&gt;

&lt;p&gt;First, think about what categories might make the most sense for your organization.  Your groupings should align with whatever dimensions you are looking to aggregate your spend data  For my situation, our primary grouping was Cost Center.&lt;/p&gt;

&lt;p&gt;Also be aware that you can build as many different cost categories as you like.  Maybe you want cost center and business group and product line…no problem.  There is a limit of 50 categories per payer account but there is no charge for this service &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating your Cost Category
&lt;/h2&gt;

&lt;p&gt;Start by logging into your payer account and navigating to the Billing Dashboard. From there choose Cost Categories from the menu on the left hand side:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YHhpkwRL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/l7tg8vtonz8oddbiupfo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YHhpkwRL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/l7tg8vtonz8oddbiupfo.png" alt="Cost Categories Menu Item" width="556" height="964"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be taken to the Cost Categories home page. To create your new Cost Category, click the orange &lt;strong&gt;Create Cost Category&lt;/strong&gt; button, which will launch the Cost Category creation “wizard”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kpF41Hu2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/w9jg0yg36rrgpzqfgqrk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kpF41Hu2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/w9jg0yg36rrgpzqfgqrk.png" alt="Cost Categories Home page with create cost category button" width="880" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 – Name
&lt;/h2&gt;

&lt;p&gt;Step 1 of this wizard is to give your Cost Category a meaningful name, e.g. Cost Center, and apply any desired tags to the Cost Category. Then click Next to proceed to the next step of the wizard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xQ13FL-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/hemhke20ir4mozyoxdz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xQ13FL-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/hemhke20ir4mozyoxdz5.png" alt="Cost Category creation wizard Step 1" width="880" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 – Define Rules
&lt;/h2&gt;

&lt;p&gt;Once you’ve created your new category, you then need to define rules for how the tool will categorize your cost.  The workflow is pretty simple:  you create your category values, and then define rules for each value.  Rules determines which charges will be assigned to that category.&lt;/p&gt;

&lt;p&gt;These rules can be based on several different dimensions like AWS account, a specific AWS service or charge type, a tag, or even other cost categories.  &lt;/p&gt;

&lt;p&gt;Rules can also have multiple dimensions in them, for example “all charges from account X for AWS S3”.   You can have up to 100 rules per cost category and they are executed in priority order from top to bottom. At the bottom of the ruleset you can also define a Default category to capture any charges that are not captured by your defined rules. I recommend you do this to avoid any uncategorized charges.&lt;/p&gt;

&lt;p&gt;For my use case the requirements were pretty simple, I built my cost center category based on AWS account boundaries, each cost center value had one or more AWS accounts assigned to it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zs4H_5DH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/rxm8593ro30vfl7l8dbe.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zs4H_5DH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/rxm8593ro30vfl7l8dbe.PNG" alt="Cost Categories Define Rules Wizard" width="880" height="1125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 – Define Split Charges
&lt;/h2&gt;

&lt;p&gt;If you want to take a specific service charge and spread it across multiple categories, you can leverage the split charge feature.  To achieve this you define a category rule to capture the charges that you want to split, and then use split charge rules to decide how you want the charges to be spread across all the remaining categories. You can read more about this particular feature in the AWS user guide on the topic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OdBYQM19--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/7jitil33fpadl0nnlijd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OdBYQM19--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/7jitil33fpadl0nnlijd.png" alt="Cost Categories Split Charge window" width="880" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Save and Finish
&lt;/h2&gt;

&lt;p&gt;Once you have finished defining all your category rules and (optional) split charge rules, click the orange Save Changes button to finish creating your cost category. You will be returned to the Cost Categories home page and your new Cost Category will show a status of Processing while the service crunches through your CUR data. When finished, the status will change to Applied.  The time it takes to show a status of Applied very much depends on how many accounts you have and where you are in the billing cycle for the month. In my environment I find it can take anywhere from 6-10 hours for a category to change from processing to applied.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dKN6cqYt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/bl9k5eynr2bbnaqyjksp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dKN6cqYt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/bl9k5eynr2bbnaqyjksp.png" alt="Cost categories home page showing category status as Applied" width="880" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing Cost Category Data
&lt;/h2&gt;

&lt;p&gt;Once your cost category shows a status of applied, you can then view it in the cost categories console. Simply click on the cost category you wish to view. On the resulting page you are presented with a graphical overview of the category distribution, a table with absolute amounts and percentage breakdowns for every category as well as any uncategorized costs.  Finally, you can download a CSV file for analysis with your spreadsheet tool of choice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ak-5j8Hn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/5cfrvlewz28ldy82ov4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ak-5j8Hn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/5cfrvlewz28ldy82ov4y.png" alt="Cost Category Details page with Download CSV button highlighted" width="880" height="701"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveat on Cost Categories reports
&lt;/h2&gt;

&lt;p&gt;I want to call out one annoyance with the native Cost Categories reports that I discovered after I started using the tool.   The reports that are shown in the cost categories console are all based on &lt;strong&gt;Amortized Charges&lt;/strong&gt; rather than the &lt;strong&gt;Unblended costs&lt;/strong&gt; that are on your AWS invoices.   (Unclear on the difference? &lt;a href="https://aws.amazon.com/blogs/aws-cloud-financial-management/understanding-your-aws-cost-datasets-a-cheat-sheet/"&gt;Check this blog post&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This caught me out when I first tried reconciling my cost categories report against my invoice. Most of my category values were off by a few hundred dollars from the invoice.   I spent a week or so trying to figure this out before my AWS TAM let me know that Cost Categories is only capable of showing Amortized Charges. Sadly there is currently no way to change this inside the cost categories tool. You can bet I’ve got my name on a PFR to fix this though! I’ll talk about how I worked around this problem in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips &amp;amp; Tricks
&lt;/h2&gt;

&lt;p&gt;Here are a few tips and tricks I’ve picked up over the past few months of working with Cost Categories that you might find useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-level hierarchies
&lt;/h2&gt;

&lt;p&gt;I mentioned before that one of the rule dimensions you can use in your category values is other cost categories. This allows you to leverage groupings you have already created to build hierarchical structures..   For example in my environment I built my initial “Cost Center” cost category based on AWS account values.  From there, I built a new cost category called Business Group that grouped multiple Cost Centers together into each business group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ett-o8tY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/j1vgoymcfbf5fjauecl2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ett-o8tY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/j1vgoymcfbf5fjauecl2.png" alt="Cost Category rule showing a multi-level heirarchy" width="880" height="705"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Categories as Code
&lt;/h2&gt;

&lt;p&gt;Once I had been working with cost categories for a while I started to find the graphical rule builder kind of tedious. I was happy to find that you also have the ability to edit your categories as a JSON file.   This makes editing of your category rules a lot faster. Not to mention, it also gives you the option to place that JSON file in a version control system. From there, you can manage the ruleset like any other code in your environment.   For you Terraform pros out there, cost categories is also &lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ce_cost_category"&gt;supported natively in the Terraform AWS provider&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eO3x5Jdg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/7raf9vgelahamnd5wcls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eO3x5Jdg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/7raf9vgelahamnd5wcls.png" alt="Cost Categories JSON file sample" width="549" height="808"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Categories in Cost Explorer
&lt;/h2&gt;

&lt;p&gt;So as I mentioned before, once created Cost Categories become available for use inside of Cost Explorer.  You can use it for filtering and grouping on spend data just like any other dimension available inside cost explorer.&lt;/p&gt;

&lt;p&gt;I leveraged this capability to get around the amortized costs limitation of the native cost categories report. Cost Explorer allowed me to build a report that I could use for my monthly invoice reconciliation process.   You can perform the following steps to get a downloadable file to use for cost allocation.&lt;/p&gt;

&lt;p&gt;Use Cost Explorer to generate a monthly report grouped by my CostCenter cost category. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mmp3ynKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/td047c3t0tvefxpn37cs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mmp3ynKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/td047c3t0tvefxpn37cs.png" alt="Cost Explorer Group by Cost Category" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to go into advanced options and choose the setting to have cost explorer show costs as unblended costs. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CHmmPtHE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/mnpuk118smub3npj8gcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CHmmPtHE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/mnpuk118smub3npj8gcp.png" alt="cost explorer advanced options show unblended costs" width="594" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have the data the way you want it, use the Download CSV function to get a CSV file. From there, you can then use that file as input data for your cost allocation process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pE1nvh04--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/l1fpo4hdc558dui1l6lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pE1nvh04--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/l1fpo4hdc558dui1l6lw.png" alt="Cost Explorer download CSV button" width="880" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Categories and CUDOS
&lt;/h2&gt;

&lt;p&gt;As I mentioned at the start of this article, once Cost Categories are created they become part of your CUR. As a result they become available for use in other AWS Cost Management tools. They can even be used by other third party tools that are leveraging the CUR. In my case this allowed me to bring my Cost Categories into the CUDOS Dashboard. As a result, I was able to use the CostCenter cost category I created to build new views into CUDOS. Below are some example screenshots where I’m leveraging Cost Categories to build new views of my CUR Data.&lt;/p&gt;

&lt;p&gt;First is a view of monthly invoiced spend grouped by individual cost center. This allows you to see a month over month trend of how much each cost center is spending.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cqNeacxN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/70cynx4za6x9rhq6w71o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cqNeacxN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/70cynx4za6x9rhq6w71o.png" alt="CUDOS Monthly spend by CostCenter" width="880" height="875"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a view showing EC2 running hours for the top 10 cost centers grouped by consumption type. In this way you can see how each cost center is performing with respect to targets for using savings instruments like reserved instances, savings plans, and spot instances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_BLxDruF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/ukrj2e8hhgz58q43fi9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_BLxDruF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/ukrj2e8hhgz58q43fi9x.png" alt="CUDOS EC2 Running Hours by CostCenter" width="880" height="966"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, below you can see an analysis of daily data transfer out grouped by Cost center. This allows you to see which cost centers are responsible for the bulk of your data transfer out charges.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WbKV42_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/xlz79j6xd6bfcm2d8eya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WbKV42_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.ops.io/remoteimages/uploads/articles/xlz79j6xd6bfcm2d8eya.png" alt="CUDOS Data Transfer by CostCenter" width="880" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In this blog post, I’ve provided you with a dive into the AWS Cost Categories feature and how to set it up. I’ve also shared how we are using it in my company and some of the lessons learned along the way. You can leverage this feature to build your own chargeback reports based on whatever model makes the most sense for your organization. You can even use the split charges feature to take shared costs and spread them across different business units.&lt;/p&gt;

&lt;p&gt;I hope you have found this post useful. Have you tried using Cost Categories in your environment? Please share your experiences or give me your feedback in the Comments section.&lt;/p&gt;

&lt;h2&gt;
  
  
  UPDATE - Cost Categories can now be Retroactive
&lt;/h2&gt;

&lt;p&gt;An exciting update to the Cost Categories service was announced on September 27, 2022.  Cost Categories now supports retroactive application of cost category rules.   When creating a new cost category, you can apply cost category rules starting any month from the previous 12 months. Similarly, while editing a cost category, you can apply cost category rules starting any month from the previous 12 months. These changes will also be reflected in AWS Cost Explorer.&lt;br&gt;
More details at &lt;a href="https://aws.amazon.com/about-aws/whats-new/2022/09/aws-cost-categories-support-retroactive-rules-application/"&gt;this blog post&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;References&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/aws-cloud-financial-management/organize-your-cost-and-usage-data-with-aws-cost-categories/"&gt;AWS Cost Categories – Launch Blog Post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-cost-categories.html"&gt;AWS Cost Categories User Guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cloudyadvice.com/2022/05/26/using-aws-cost-explorer-for-forecasting/"&gt;CloudyAdvice – Using AWS Cost Explorer for Forecasting&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/aws-cost-management/"&gt;AWS Cloud Financial Management&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pages.awscloud.com/aws-cfm-talks-how-to-design-your-AWS-cost-allocation-strategy-01122022.html"&gt;CFM Talks Video – How to Design your AWS Cost Allocation Strategy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.finops.org/"&gt;FinOps Foundation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>finops</category>
      <category>cloudops</category>
    </item>
    <item>
      <title>Easily Query your Cloud Inventory with Steampipe</title>
      <dc:creator>Mike Graff</dc:creator>
      <pubDate>Tue, 27 Sep 2022 22:05:21 +0000</pubDate>
      <link>https://dev.to/aws-builders/easily-query-your-cloud-inventory-with-steampipe-2af3</link>
      <guid>https://dev.to/aws-builders/easily-query-your-cloud-inventory-with-steampipe-2af3</guid>
      <description>&lt;h2&gt;Cloud Inventory is a Challenge&lt;/h2&gt;

&lt;p&gt;Anyone who has worked with AWS for a while will be quite familiar with the difficulties of getting a complete picture of the inventory of resources in your accounts.   While AWS has made some limited strides in this area with tools like the &lt;a href="https://aws.amazon.com/about-aws/whats-new/2021/09/amazon-ec2-global-view-console-regions/" rel="noopener"&gt;EC2 Global View&lt;/a&gt; and the ability to get a count of all VPCs in the VPC dashboard, the bottom line is that AWS does not provide a comprehensive inventory solution for an AWS account or group of accounts.&lt;/p&gt;

&lt;p&gt;While there are many excellent third party commercial tools you can use to solve this problem, not everyone (including me!) has the budget available to pay for these tools.   So for the past month or two I've been spending time looking at some open source tools to add to my team's toolchain to help us with the inventory problem.   One of the tools I've been looking at is an interesting solution called Steampipe.  In this post I'm going to dive into this tool and share some of the things I've learned about it.&lt;/p&gt;

&lt;h2&gt;Steampipe - Query your cloud inventory like it's 1992&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://steampipe.io/" rel="noopener"&gt;Steampipe.io&lt;/a&gt; is an open source tool that is maintained by the commercial tool company &lt;a href="https://turbot.com" rel="noopener"&gt;Turbot&lt;/a&gt;.   In a nutshell, the software allows you to query your favorite cloud services with SQL.  By providing a consistent command line interface that works across multiple IaaS, PasS and SaaS services, Steampipe aims to reduce the time wasted on context switching between different cloud provider's native interfaces.  As the end user, you write your queries in a consistent SQL syntax, and Steampipe translates that query into native API calls that are executed in real time against the cloud service's API.&lt;/p&gt;

&lt;p&gt;Interaction with various cloud service's APIs is handled via Steampipe plugins for each service.  As of this writing there are 86 different plugins available on the &lt;a href="https://hub.steampipe.io/plugins" rel="noopener"&gt;Steampipe Hub&lt;/a&gt;, including plugins for all the major cloud players (AWS, Alibaba, Azure, Cloudflare, GCP, Digital Ocean, IBM, Oracle, Heroku), SaaS services (Datadog, PagerDuty, Salesforce, Stripe, Twilio, Zendesk, Zoom), as well as some more intriguing options like VMware vSphere, Terraform, Reddit, and Slack.&lt;/p&gt;

&lt;h2&gt;Getting Started&lt;/h2&gt;

&lt;p&gt;The easiest way to get started playing with Steampipe is to install it on your local workstation.   The Steampipe Downloads page provides step by step instructions for installation on MacOS, Linux, and Windows operating systems.  &lt;/p&gt;

&lt;p&gt;On a Mac with the &lt;a href="https://brew.sh" rel="noopener"&gt;Homebrew&lt;/a&gt; package manager installed, the process could not be any simpler:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tap Turbot's Cask:  &lt;code&gt;~$brew tap turbot/tap&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install Steampipe: &lt;code&gt;~$brew install steampipe&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Validate the installation is working by checking the installed version of Steampipe:          &lt;code&gt;~$steampipe - v&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you have the core Steampipe engine installed, you need to install plugins for whichever cloud services you want to query.   First, let's install the &lt;a href="https://hub.steampipe.io/plugins/turbot/steampipe" rel="noopener"&gt;Steampipe plugin&lt;/a&gt; which will allow us to query Steampipe components, such as the available plugins in the Steampipe hub.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~$ steampipe plugin install steampipe

steampipe            [====================================================================] Done                

Installed plugin: steampipe@latest v0.5.0
Documentation:    https://hub.steampipe.io/plugins/turbot/steampipe&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, let's install the &lt;a href="https://hub.steampipe.io/plugins/turbot/aws" rel="noopener"&gt;AWS plugin&lt;/a&gt; so we can start querying our AWS environments.  Use the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~$ steampipe plugin install aws

aws                  [====================================================================] Done                

Installed plugin: aws@latest v0.78.0
Documentation:    https://hub.steampipe.io/plugins/turbot/aws&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now that we have our AWS plugin installed, we need to do configure some credentials for the plugin so we can start querying our AWS accounts.&lt;/p&gt;

&lt;h2&gt;Configure Credentials&lt;/h2&gt;

&lt;h3&gt;Basic Setup&lt;/h3&gt;

&lt;p&gt;When you install the Steampipe AWS plugin, the tool will automatically create a configuration file for you located at the following path:  &lt;code&gt;~/.steampipe/config/aws.spc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Within this configuration file you can setup one or more AWS accounts to query with Steampipe.   You can setup credentials directly in the aws.spc file if you want, but even more handy is the fact that Steampipe can refer to credential profiles you've already setup for AWS CLI.   Best of all, you can even use AWS SSO profiles with Steampipe!&lt;/p&gt;

&lt;p&gt;Credentials statements in my aws.spc file look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;connection "itprod" {
  plugin = "aws"
  profile = "sso-itprod"
  regions = ["*"]
}
connection "itshared"
  plugin = "aws"
  profile = "sso-itshared"
  regions = ["*"]
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, each connection entry in my aws.spc starts with a name definition, followed by which plugin you are using, the profile name in my &lt;code&gt;~./aws/config&lt;/code&gt; file, and finally a region specification.  You can put a list of individual regions here or use * to query all regions simultaneously.  &lt;/p&gt;

&lt;h3&gt;Advanced Configuration&lt;/h3&gt;

&lt;p&gt;If you have a multi account setup, and you've configured multiple connection entries in your aws.spc file, you can also create what is called an "aggregator connection" which allows you to query against multiple connections from a plugin in a single query.  &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;connection "aws_all" {
  type = aggregator
  plugin = aws
  connections = ["itprod", "itshared"]
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can even use wildcards in your aggregator specification, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;connection "aws_it_all" {
  type = aggregator
  plugin = aws
  connections = ["it*"]
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Another handy capability comes into play if you are running Steampipe on an EC2 instance inside your AWS Account.  If you have an &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html" rel="noopener"&gt;IAM Instance profile&lt;/a&gt; attached to the instance with appropriate permissions, Steampipe will automatically use that IAM role with no other credentials being configured.&lt;/p&gt;

&lt;p&gt;Now that we have some credentials configured for Steampipe, let's see what we can do with this tool!&lt;/p&gt;

&lt;h2&gt;Basic Queries&lt;/h2&gt;

&lt;p&gt;The Steampipe AWS plugin organizes the many AWS services into discrete tables that you can then write queries against.  As of this writing there are 344 discrete tables defined in the AWS plugin, you can review them all &lt;a href="https://hub.steampipe.io/plugins/turbot/aws/tables" rel="noopener"&gt;here&lt;/a&gt;.   You can run queries in two different modes with Steampipe:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enter an interactive query console by entering the command &lt;code&gt;steampipe query&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run a specific query directly by entering it all in a single command: &lt;code&gt;steampipe query "select * from cloud"&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I believe it is easier to get started using the interactive query console as it provides you with hints and autocomplete as you write your queries.   Let's enter the console and see what commands are available:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;➜  steampipe query
Welcome to Steampipe v0.15.4
For more information, type .help
&amp;gt; .help
Welcome to Steampipe shell.

To start, simply enter your SQL query at the prompt:

  select * from aws_iam_user

Common commands:

.help     Show steampipe help                           
.inspect  View connections, tables &amp;amp; column information 
.exit     Exit from steampipe terminal                  

Advanced commands:

.cache [mode]        Enable, disable or clear the query cache                                                     
.clear               Clear the console                                                                            
.connections         List active connections                                                                      
.header on|off       Enable or disable column headers                                                             
.multi on|off        Enable or disable multiline mode                                                             
.output [mode]       Set output format: csv, json, table or line                                                  
.quit                Exit from steampipe terminal                                                                 
.search_path         Display the current search path, or set the search-path by passing in a comma-separated list 
.search_path_prefix  Set a prefix to the current search-path                                                      
.separator           Set csv output separator                                                                     
.tables              List or describe tables                                                                      
.timing on|off       Enable or disable query execution timing                                                     &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As the help file suggests, you can use the .tables command to get a list of all the tables available in Steampipe:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8GlGK4nU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/steampipe_tables-1024x412.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8GlGK4nU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/steampipe_tables-1024x412.jpg" alt="" width="880" height="354"&gt;&lt;/a&gt;Steampipe .tables command&lt;/p&gt;

&lt;p&gt;You can use the .inspect command to view details on connections and tables.   Inspect is particularly powerful as you can use it to drill into a specific table to see what fields are available.  For example here's a screenshot showing the &lt;code&gt;.inspect aws_vpc&lt;/code&gt; command result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--99PZHmzZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/steampipe_inspect-1024x377.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--99PZHmzZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/steampipe_inspect-1024x377.jpg" alt="" width="880" height="324"&gt;&lt;/a&gt;Steampipe .inpsect aws_vpc command&lt;/p&gt;

&lt;p&gt; Once you've seen the connections and tables, you can get an idea of what types of queries you can run.   As the help file suggests, you can start by getting a list of all the IAM users in all your configured accounts with the command &lt;code&gt;select * from aws_iam_user&lt;/code&gt; which returns a table like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nlzoRES9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/select_iam_users-1024x300.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nlzoRES9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/select_iam_users-1024x300.jpg" alt="" width="880" height="258"&gt;&lt;/a&gt;Steampipe query for all IAM users&lt;/p&gt;

&lt;p&gt;If you have an aggregator configuration setup, you will get results for all configured AWS accounts by default.  If you want to limit your scope to a specific AWS Account, simply prefix the table name with the connection name e.g. &lt;code&gt;select * from itshared.aws_ec2_instance&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nNOIUzJw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/select_ec2_instances-1024x178.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nNOIUzJw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/select_ec2_instances-1024x178.jpg" alt="" width="880" height="153"&gt;&lt;/a&gt;Steampipe query for EC2 instances in a specific account&lt;/p&gt;

&lt;h2&gt;Advanced Queries&lt;/h2&gt;

&lt;p&gt;If you review the table definitions published on the &lt;a href="https://hub.steampipe.io/plugins/turbot/aws/tables" rel="noopener"&gt;AWS plugin page at Steampipe Hub&lt;/a&gt;, you will see lots of more advanced examples of what you can do with Steampipe.   For example, let's say you want to get a count of IAM access keys that are between 45 and 90 days old:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Mt-wXwt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/select_access_keys_45_to_90_days-1024x274.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Mt-wXwt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/select_access_keys_45_to_90_days-1024x274.jpg" alt="" width="880" height="235"&gt;&lt;/a&gt;Steampipe query of access keys between 45 and 90 days old&lt;/p&gt;

&lt;p&gt;Or perhaps a list of your S3 buckets that are not encrypted:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IfZm18-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/select_unecrypted_buckets-2-1024x421.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IfZm18-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/select_unecrypted_buckets-2-1024x421.jpg" alt="" width="880" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe you'd like to get a quick count of EC2 instances grouped by region across all your accounts?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bv3F5JUb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/count-instance-by-region-300x289.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bv3F5JUb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/count-instance-by-region-300x289.jpg" alt="" width="300" height="289"&gt;&lt;/a&gt;Steampipe query counting number of EC2 instances by region&lt;/p&gt;

&lt;p&gt;Lastly, let's get really fancy and create an age table of all our EC2 instances:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FRiAbw4n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/steampipe-ec2-instance-age-table-2-1024x531.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FRiAbw4n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/09/steampipe-ec2-instance-age-table-2-1024x531.jpg" alt="" width="880" height="456"&gt;&lt;/a&gt;Steampipe EC2 instance age table&lt;/p&gt;

&lt;h2&gt;Wrap-up&lt;/h2&gt;

&lt;p&gt;As you can hopefully see from this brief introduction, there is a ton of things you can do with this tool, especially leveraging the power of SQL.  While I personally do not have a lot of SQL experience, I was still able to get up and running pretty quickly following the excellent documentation and examples provided by the Steampipe project.   &lt;/p&gt;

&lt;p&gt;In the future I hope to do a follow up post on some of the more advanced capabilities of Steampipe including the ability to serve custom dashboards based on the Steampipe engine.   In the meantime, if you've tried this tool yourself, please share your experience with me in the comments section.&lt;/p&gt;

&lt;p&gt;Happy querying!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>operations</category>
    </item>
    <item>
      <title>Implementing CUDOS for an Enterprise - Part 2: Filtering Data using Row Level Security</title>
      <dc:creator>Mike Graff</dc:creator>
      <pubDate>Fri, 08 Jul 2022 20:21:53 +0000</pubDate>
      <link>https://dev.to/aws-builders/implementing-cudos-for-an-enterprise-part-2-filtering-data-using-row-level-security-1g2p</link>
      <guid>https://dev.to/aws-builders/implementing-cudos-for-an-enterprise-part-2-filtering-data-using-row-level-security-1g2p</guid>
      <description>&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;In my first post on the CUDOS solution, I showed you how you can &lt;a rel="noreferrer noopener" href="https://cloudyadvice.com/2022/04/29/implementing-cudos-cost-intelligence-dashboards-for-an-enterprise/"&gt;implement implement SSO access to CUDOS using AWS Single Sign-on service&lt;/a&gt;.   Leveraging this capability you can enable users to sign in to QuickSight using their corporate credentials and avoid having to give them full access to the AWS console.  Now that we've got our users setup via SSO, let's leverage these same user objects to enable additional functionality.&lt;/p&gt;

&lt;p&gt;By default, when a user accesses your CUDOS dashboard, they will have the ability to see billing data for every account in your AWS organization.  If you have a large environment with dozens or even hundreds of AWS accounts, this may be less than desirable.  Users may have a hard time figuring out how to just see the data for accounts they are interested in, or as an admin you may have a desire to limit what data they can see.&lt;/p&gt;

&lt;p&gt;In this article, I'm going to show you a method to limit what account data any given user can see in the CUDOS dashboard.  Once implemented, the user will only be able to see billing data for the accounts that you have granted them access to.   &lt;/p&gt;

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

&lt;p&gt;There are two primary components to this solution.   The first is &lt;a rel="noreferrer noopener" href="https://docs.aws.amazon.com/quicksight/latest/user/creating-quicksight-groups.html"&gt;QuickSight Groups&lt;/a&gt;.   QuickSight groups are just what you would expect, a feature that allows you to organize sets of users into groups that make it easier to manage access and security.   When I first started working with QuickSight, groups were an absolute pain to manage.  Originally they could not be managed via the AWS console...in fact they were not even &lt;em&gt;visible&lt;/em&gt; in the console and could only be created, managed or listed using AWS CLI commands.  Good news for you however is that as of March 2022 you can now &lt;a rel="noreferrer noopener" href="https://aws.amazon.com/about-aws/whats-new/2022/03/amazon-quicksight-groups-management-ui/"&gt;manage QuickSight Groups in the QuickSight console&lt;/a&gt;.   &lt;/p&gt;

&lt;p&gt;The second component of our solution is something called &lt;a rel="noreferrer noopener" href="https://docs.aws.amazon.com/quicksight/latest/user/row-level-security.html"&gt;row-level security (RLS)&lt;/a&gt;.  This is a feature of the Enterprise Edition of QuickSight that allows you to restrict access to a dataset using a set of dataset rules.  Once implemented, dataset owners can still see all the data, but dataset readers will be restricted based on the criteria in your ruleset.   Access to a dataset can be restricted by user/group based rules, tag-based rules, or both.  Tag based rules are really targeted towards anonymous users if you are doing something like an embedded dashboard, so we will be focusing on &lt;a rel="noreferrer noopener" href="https://docs.aws.amazon.com/quicksight/latest/user/restrict-access-to-a-data-set-using-row-level-security.html"&gt;user/group based rules&lt;/a&gt; for our architecture.&lt;/p&gt;

&lt;p&gt;The diagram below outlines how the components outlined below come together for our solution.   &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;QuickSight users are placed into QuickSight Groups&lt;/li&gt;
&lt;li&gt;An input file is prepared in CSV format containing the dataset rules and stored in an S3 bucket&lt;/li&gt;
&lt;li&gt;The input file is imported into a QuickSight dataset&lt;/li&gt;
&lt;li&gt;The rules dataset is used to apply row-level security against the appropriate CUDOS datasets&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MjAKH3Zf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/QuickSight-RLS-Security-1024x761.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MjAKH3Zf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/QuickSight-RLS-Security-1024x761.png" alt="" width="880" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that I've given you a high level overview of the solution, let's walk through the implementation in detail.&lt;/p&gt;

&lt;h2&gt;Implementation&lt;/h2&gt;

&lt;h3&gt;Step 1 - Create QuickSight groups&lt;/h3&gt;

&lt;p&gt;The foundation for implementing your filtering is the creation of one or more QuickSight groups.  These groups will be used later in our row-level security dataset to tell QuickSight how to filter data set views.  You will need to create a QuickSight Group for each set of accounts that you want to group together.  &lt;/p&gt;

&lt;p&gt;To create a QuickSight group:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign in to the AWS Console in the account where you are hosting QuickSight, navigate to the QuickSight service.&lt;/li&gt;
&lt;li&gt;On the QuickSight home page, click the menu in the upper right and select &lt;strong&gt;Manage QuickSight&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;On the QuickSight Management page, select &lt;strong&gt;Manage Groups&lt;/strong&gt; from the left hand menu.&lt;/li&gt;
&lt;li&gt;On the Manage Groups page click the blue &lt;strong&gt;New Group&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;On the Create a New Group screen, enter a Group name. Note the group name cannot contain any spaces or certain special characters. Optionally enter a group description and click the blue &lt;strong&gt;Create&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dCwhZThc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/cloudyadvice.com/wp-content/uploads/2022/05/QuickSight-select-Manage-groups-3.png%3Fssl%3D1" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--dCwhZThc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/cloudyadvice.com/wp-content/uploads/2022/05/QuickSight-select-Manage-groups-3.png%3Fssl%3D1" width="453" height="906"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y3M2-snx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/cloudyadvice.com/wp-content/uploads/2022/05/New-group-button-1.png%3Fssl%3D1" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y3M2-snx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/cloudyadvice.com/wp-content/uploads/2022/05/New-group-button-1.png%3Fssl%3D1" width="444" height="296"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zqBWw1lC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/cloudyadvice.com/wp-content/uploads/2022/05/Create_a_new_group.png%3Fssl%3D1" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--zqBWw1lC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/cloudyadvice.com/wp-content/uploads/2022/05/Create_a_new_group.png%3Fssl%3D1" width="748" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PPVgp3r4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/new-group-add-user-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PPVgp3r4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/new-group-add-user-1.png" alt="" width="880" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6.  After you create your new group, you will be take to the group membership page where you can now add QuickSight users to the group.  Click the blue &lt;strong&gt;Add User&lt;/strong&gt; button and add new users by user name or email address.&lt;/p&gt;

&lt;p&gt;Repeat this process for each group that you need to create.   My recommendation is to create groups for each logical grouping of accounts in your AWS Organization, could be by project team, business group, or whatever works best for you.  Note also that a user can be a member of more than one QuickSight group, for example if you want to give them access to more than one set of accounts.   In addition to team specific groups, I recommend creating a group called "FullAccess" for any QuickSight users that you want to be able to see all your AWS Accounts in the dataset. Once you've created your QuickSight Groups, it's time to setup your rules mapping file.&lt;/p&gt;

&lt;h3&gt;Step 2: Row Level Security Rules Input file&lt;/h3&gt;

&lt;p&gt;As documented in the QuickSight user guide, you can setup RLS with user-based rules by creating a query or a file that feeds the rules dataset.  I'm not really a SQL guy, so I find the file based option to be simplest to setup and it makes it easy for me to change my ruleset as needed.  I just edit the file and replace the version stored in the S3 bucket (more on this process later).  To get started, create a new comma-separated value (CSV) file with two columns in it.  Column A header should be "GroupName" and column B header should be "account_id".  &lt;/p&gt;

&lt;p&gt;Next, we will populate the GroupName column with the QuickSight Group names we created in step 1. In the account_id column, you will enter the AWS Account number you want that group to have access to, enclosed in double quotes. If you want to give a single QuickSight group access to more than one account, you will need to create a row for each account_id, all using the same GroupName. I was originally told by some folks at AWS that you could enter multiple account ids in a single column, separated by commas, but I could never get that to work and settled on this file format through trial and error.  To grant your "FullAccess" group access to all data in the dataset, create a row with that group name and leave the account_id column empty.  See the screenshot at right shows an example of what your file should look like.   &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vumwhQtZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/CUDOS_dataset_rls-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vumwhQtZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/CUDOS_dataset_rls-2.png" alt="" width="320" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;lt;!-- /wp:column --&amp;gt;&lt;/p&gt;

&lt;p&gt;Save your file, giving it a name like "cudos_dataset_rls.csv" or something similar.   With our file created, we are now ready for the next step, creating the rules QuickSight dataset.&lt;/p&gt;

&lt;h3&gt;Step 3: Create a CUDOS RLS Rules Dataset&lt;/h3&gt;

&lt;p&gt;We need to create a new QuickSight Dataset to store our RLS rules so that we can then apply them against our CUDOS datasets.  Since it is very likely we will want to make changes to these rules over time, we want to create a dataset that is looking at specific location in an S3 bucket rather than just uploading the file into a dataset.   By using the S3 method, whenever we want to update our RLS rules, all we have to do is upload a new version of the file to S3.&lt;/p&gt;

&lt;p&gt;In preparation for creating the S3 dataset, upload the CSV file you created in step 2 to a private S3 bucket in the AWS account where you are running QuickSight. This can be a new purpose-created S3 bucket or you can use an existing bucket, for example the bucket you use to store your QuickSight queries results. Then, we need to create an &lt;a href="https://docs.aws.amazon.com/quicksight/latest/user/supported-manifest-file-format.html" rel="noreferrer noopener"&gt;S3 manifest file&lt;/a&gt; that will tell QuickSight where our file is located in S3.   &lt;/p&gt;

&lt;p&gt;An S3 manifest is a JSON file that contains the S3 url of the file location.  Create a new file called "CUDOS_manifest.json" and set it up like the example below, replacing "YOUR_BUCKET_NAME" and "YOURFILENAME" with the proper values for your file.  &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
    "entries": [{
        "url": "s3://YOUR_BUCKET_NAME/YOURFILENAME.csv",
        "mandatory": true
    }]
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can store the manifest file in the same S3 bucket where you placed your CSV file.  With the files in S3 prepared, you can follow this process to create the new dataset.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F6-K7c3F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/New_Data_Set.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F6-K7c3F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/New_Data_Set.png" alt="" width="570" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol id="block-1e21f5b0-c887-46ee-ae9b-c958c91595dd"&gt;
&lt;li&gt;Log in to the AWS Console in the account where you are running QuickSight, navigate to the QuickSight service.&lt;/li&gt;
&lt;li&gt;From the QuickSight home page, click &lt;strong&gt;Datasets&lt;/strong&gt; on the left hand menu bar.&lt;/li&gt;
&lt;li&gt;On the Create Datasets screen, click S3.&lt;/li&gt;
&lt;li&gt;On the Datasets page, click the blue &lt;strong&gt;New dataset&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--scbOjXis--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/new-s3-datasource.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--scbOjXis--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/new-s3-datasource.png" alt="" width="879" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5.  For data source name enter "CUDOS_Dataset_rules" and enter the S3 URL of your manifest file in the "Upload a manifest file" field. Make sure the "URL" radio button is selected and click Connect&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MVWJ5jd8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/Finish-dataset-creation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MVWJ5jd8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/Finish-dataset-creation.png" alt="" width="879" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6.  On the Finish dataset creation screen, click the Edit/Preview data button. &lt;/p&gt;

&lt;p&gt;7.  In the dataset preview screen, we need to verify the the account_ID field is a String datatype.  If it appears as an Integer, change the data type for account_id to String.   Follow the screenshots below for how to do this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vnGsXYr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/change-data-type-1024x721.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vnGsXYr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/change-data-type-1024x721.png" alt="" width="880" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is very important to make this change because it matches the same data type as the account_id field in all of the CUDOS datasets and prevents the loss of any leading or trailing zeros on an account_id.  After you've finished changing the field type, click Save &amp;amp; publish in the upper right to save your dataset. &lt;/p&gt;

&lt;p&gt;With our rules dataset prepared, we can move on to the last step, applying these rules against the CUDOS datasets.   &lt;/p&gt;

&lt;h3&gt;Step 4: Apply Row Level Security to CUDOS datasets&lt;/h3&gt;

&lt;p&gt;On each of the datasets that the CUDOS dashboard is using, we will define row level security for the dataset by following these steps:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ga-8zjdQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/manage-dataset-security-982x1024.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ga-8zjdQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/manage-dataset-security-982x1024.png" alt="" width="880" height="918"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol id="block-6ebe549e-8e76-4702-a956-17246b3024dc"&gt;
&lt;li&gt;In the QuickSight management console, choose Datasets from the left hand navigation menu.&lt;/li&gt;
&lt;li&gt;Click the dataset name, e.g. "cudos_summary_view"&lt;/li&gt;
&lt;li&gt;A dataset details window will pop open showing you more information about the dataset.&lt;/li&gt;
&lt;li&gt; Click the button bottom left labeled &lt;strong&gt;Row-level security&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C3nA3Zok--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/apply-RLS-dataset-853x1024.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C3nA3Zok--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/apply-RLS-dataset-853x1024.png" alt="" width="853" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5.  You will be taken to the Set up row-level security screen.  Click the double-caret to expand the User-based rules section.&lt;/p&gt;

&lt;p&gt;6.  You will see that the selected dataset rules is currently set to None, and below you will see a list of all QuickSight datasets in your environment.&lt;/p&gt;

&lt;p&gt;7.  Click the radio button next to the CUDOS_dataset_rules dataset you created in Step 3 to select it.&lt;/p&gt;

&lt;p&gt;8. Click the blue Apply dataset button to apply these rules against your dataset.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--83-g_06z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/confirm-apply-RLS-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--83-g_06z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/confirm-apply-RLS-2.png" alt="" width="880" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;9.   A confirmation window will open, confirming that the dataset rules will use the GroupName column to find matching rules.  Click &lt;strong&gt;Apply and Activate&lt;/strong&gt;.   &lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wDufu8ZZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/RLS-applied-to-dataset-2-1024x352.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wDufu8ZZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/RLS-applied-to-dataset-2-1024x352.png" alt="" width="880" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;10.  You will be taken back to the row-level security screen, where you should now see your dataset listed under the Selected Dataset Rules.&lt;/p&gt;

&lt;p&gt;To ensure the security filtering is consistent across all the CUDOS dashboard tabs, you will need to repeat these steps for all of the CUDOS related datasets.  As of this writing, these are the CUDOS datasets that I applied the rules against:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cudos_summary_view&lt;/li&gt;
&lt;li&gt;cudos_compute_savings_plan_eligible_spend&lt;/li&gt;
&lt;li&gt;cudos_s3_view&lt;/li&gt;
&lt;li&gt;cudos_ec2_running_cost&lt;/li&gt;
&lt;li&gt;cctd_view&lt;/li&gt;
&lt;li&gt;cudos_cur&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Test!&lt;/h2&gt;

&lt;p&gt;Once you have completed applying the RLS ruleset against each of the CUDOS datasets, you should test to confirm that row-level security is working correctly.  You can do this by logging into the QuickSight dashboard using a user that is a member of group that has limited access, and validate that the AWS Account IDs shown are only the ones specified in your rules dataset.   You should also access the dashboard as a user who is a member of the FullAccess group and validate that all AWS Account IDs are still visible.&lt;/p&gt;

&lt;h2&gt;Updating RLS rules&lt;/h2&gt;

&lt;p&gt;Over time you may find that you wish to update your row-level security rules to reflect new AWS accounts or new QuickSight groups.  The process to update your rules is simple:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bnXOWJhf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/refresh-dataset-now-1024x1012.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bnXOWJhf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/refresh-dataset-now-1024x1012.png" alt="" width="880" height="870"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol id="block-8c6ff365-5b34-4a12-9ea1-b3409d12c5c4"&gt;
&lt;li&gt;Update your CSV file with the new rules, adding new QuickSight groups or account_id values as needed.&lt;/li&gt;
&lt;li&gt;Upload the updated CSV file to your S3 bucket and replace the existing file.&lt;/li&gt;
&lt;li&gt;Navigate to the QuickSight management console&lt;/li&gt;
&lt;li&gt;Click on Datasets in the left hand menu.&lt;/li&gt;
&lt;li&gt;On the datasets screen, click your CUDOS_dataset_rules dataset.&lt;/li&gt;
&lt;li&gt;On the dataset summary screen, click the Refresh now button&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_C3xaBH9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/refresh-now-1024x366.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_C3xaBH9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/refresh-now-1024x366.png" alt="" width="880" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7.  A dialog box will open, click the blue Refresh button to complete the refresh of your dataset.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wk20qN4F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/refresh-warning-1024x328.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wk20qN4F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cloudyadvice.com/wp-content/uploads/2022/05/refresh-warning-1024x328.png" alt="" width="880" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;8.  A "Warning" dialog will open, click Ok to confirm the dataset refresh.  Afterwards you will get a Success dialog box confirming that the refresh has been queued.  Click Ok.&lt;/p&gt;

&lt;p&gt;QuickSight will automatically apply the new rules against your CUDOS dataset when the refresh has completed.&lt;/p&gt;

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

&lt;p&gt;In this post, I've shown you a method to filter what data your QuickSight users can view in your CUDOS dashboard.  Implementing this feature was incredibly useful in my environment where I have over 150 AWS accounts and I might only want a particular user to be able to view billing data for just a few accounts.  It also makes it easier for your users since the data is pre-filtered for them and they don't have to manually filter out accounts they are not interested in.&lt;/p&gt;

&lt;p&gt;I hope you've found this article useful, and please leave a comment if you have any questions or suggestions for improvement.    Once again, I also have to give a big shout out to Aaron Edell, GTM for Customer Cloud Intelligence for AWS, who guided me on implementing the row-level security solution for QuickSight and answered the many questions I had.  &lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/quicksight/latest/user/creating-quicksight-groups.html" rel="noreferrer noopener"&gt;Amazon QuickSight User Guide - Creating and managing groups in Amazon QuickSight&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="noreferrer noopener" href="https://docs.aws.amazon.com/quicksight/latest/user/row-level-security.html"&gt;Amazon QuickSight User Guide - Using row-level security (RLS) in Amazon QuickSight&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>finops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Implementing CUDOS Cost Intelligence Dashboards for an Enterprise</title>
      <dc:creator>Mike Graff</dc:creator>
      <pubDate>Fri, 29 Apr 2022 22:29:06 +0000</pubDate>
      <link>https://dev.to/aws-builders/implementing-cudos-cost-intelligence-dashboards-for-an-enterprise-5bi8</link>
      <guid>https://dev.to/aws-builders/implementing-cudos-cost-intelligence-dashboards-for-an-enterprise-5bi8</guid>
      <description>&lt;h2&gt;
  
  
  Part 1 - Deployment and SSO Integration
&lt;/h2&gt;

&lt;p&gt;At my day job I recently led a project to move away from CloudHealth for cost reporting and implement some new tools to replace the functionality of CloudHealth.  CloudHealth is a great tool but my company no longer wanted to pay a percentage of our spend just to get the reporting capabilities, especially as our spend continues to grow.  While I found that native tools like &lt;a rel="noreferrer noopener" href="https://aws.amazon.com/aws-cost-management/aws-cost-explorer/"&gt;AWS Cost Explorer&lt;/a&gt; and &lt;a rel="noreferrer noopener" href="https://aws.amazon.com/aws-cost-management/aws-cost-categories/"&gt;Cost Categories&lt;/a&gt; met a lot of our requirements, I wanted some additional analytics tools that allowed us to see billing data across multiple AWS accounts in a single dashboard, as well as provide a means to restrict users to only be able to see certain AWS account&lt;/p&gt;

&lt;p&gt;To solve this requirement, my AWS Technical Account Manager let me know about a set of open source QuickSight Cost Intelligence dashboards developed by AWS.   The suite includes the CUDOS Dashboard, Cost Intelligence Dashboard, Trusted Advisor Dashboard, and Trends dashboard and are all built using a combination of AWS services including the Cost and Usage Report, S3, Glue, Athena and QuickSight.  You can read up more on these offerings and the underlying architecture in this &lt;a href="https://aws.amazon.com/blogs/mt/visualize-and-gain-insights-into-your-aws-cost-and-usage-with-cloud-intelligence-dashboards-using-amazon-quicksight/" rel="noopener noreferrer"&gt;AWS blog post&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This article is not going to be a walkthrough on how to setup these dashboards from scratch. There is already an excellent guide on this in the form of a series of &lt;a rel="noreferrer noopener" href="https://wellarchitectedlabs.com/cost/200_labs/200_cloud_intelligence/"&gt;AWS Well Architected Labs&lt;/a&gt; that guide you through the whole process.  You can also use &lt;a href="https://d1s0yx3p3y3rah.cloudfront.net/anonymous-embed?dashboard=cudos" rel="noreferrer noopener"&gt;this demo site from AWS&lt;/a&gt; to get hands on with the dashboards to check out their capabilities.  I suggest you go through these labs to get the dashboards setup and then come back here and read my posts for a series of tips for how to implement this solution for a large enterprise supporting multiple different cloud teams.&lt;/p&gt;

&lt;p&gt;For this series of articles I'm going to be primarily focusing on the CUDOS dashboard which looks like this:&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%2F1j06ja1ke6pmhibt8h99.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%2F1j06ja1ke6pmhibt8h99.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part 1 of this series will be on Implementing AWS SSO for QuickSight.  Future posts will cover topics like customizing and publishing dashboards to users, as well as how to implement row level security in QuickSight to filter access for different account owners.&lt;/p&gt;

&lt;h2&gt;Implementing AWS SSO for QuickSight&lt;/h2&gt;

&lt;p&gt;To make things simple, I deployed my QuickSight dashboards in my AWS organization payer account aka the management account.  However I don't want to allow everyone who needs access to these dashboards to login to the AWS Console on my management account.   Instead, I wanted them to login to QuickSight directly via SSO.   In my environment I already have AWS SSO implemented to allow users to access the AWS Console using their corporate credentials, so I was able to extend that capability to provide a login for QuickSight.  If you need guidance on setting up AWS SSO for the first time, I refer you to AWS' &lt;a href="https://docs.aws.amazon.com/singlesignon/latest/userguide/getting-started.html" rel="noreferrer noopener"&gt;documentation on the subject&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;AWS also provides pretty good documentation on how to implement various IdPs with Amazon QuickSight, but in this post I've distilled down a step-by-step guide for implementing AWS Single Sign-On as your IdP for QuickSight (assumes you already have AWS Single Sign-On implemented for AWS Console logins).  To complete the setup, there are four tasks we much complete:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure a new Application in the IdP (AWS SSO)&lt;/li&gt;
&lt;li&gt;Create new SAML IdP in AWS IAM and configure it for QuickSight&lt;/li&gt;
&lt;li&gt;Update attribute mappings in AWS SSO&lt;/li&gt;
&lt;li&gt;Assign users to your new Application in AWS SSO&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id="CreateNewApp"&gt;Create new Application in AWS Single Sign-On&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Login to your AWS Organization Management account, navigate to the AWS Single Sign-on service&lt;/li&gt;
&lt;li&gt;On the left hand bar, click on &lt;strong&gt;Applications&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;On the Applications screen, click the blue &lt;strong&gt;Add a new application&lt;/strong&gt; button&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;4. In the search box, type "&lt;strong&gt;QuickSight&lt;/strong&gt;"&lt;/p&gt;

&lt;p&gt;5. When Amazon QuickSight is displayed, click on it to select it and then click the blue &lt;strong&gt;Add Application&lt;/strong&gt; button at the bottom of the screen&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%2Fwqjg7wnyqdfe0544kl2m.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%2Fwqjg7wnyqdfe0544kl2m.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6. The next screen will allow you to enter configuration details for your application.  Click on the &lt;strong&gt;View instructions&lt;/strong&gt; link to get the specific configuration instructions for Amazon QuickSight, which I will walk you through below &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%2F9wltf2v3ievgsygh22fz.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%2F9wltf2v3ievgsygh22fz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7.  Under Details, enter a display name and description for your app. You can accept the defaults if you wish.&lt;/p&gt;

&lt;p&gt;8. In the &lt;strong&gt;AWS SSO metadata&lt;/strong&gt; section, click the link to download the AWS SSO Metadata file to your computer.  We will use this file later when we complete the IAM configuration.&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%2Faz5hh6bflf5zxdqrs5fz.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%2Faz5hh6bflf5zxdqrs5fz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;9. Under &lt;strong&gt;Application properties&lt;/strong&gt;, ensure Relay State has the value `https://quicksight.aws.amazon.com` and set the Session duration to whatever value you prefer...I recommend keeping it to 4 hours or less.&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%2F5pyiou04vp7oevlz2lzl.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%2F5pyiou04vp7oevlz2lzl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;10. Under &lt;strong&gt;Application metadata&lt;/strong&gt;, ensure that the Application ACS URL is set to `https://signin.aws.amazon.com/saml` and the SAML audience should be set to `urn:amazon:webservices`&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%2F6pv2if69ry7tvod2godw.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%2F6pv2if69ry7tvod2godw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Save Changes&lt;/strong&gt; to save your SAML configuration.   Now we are ready to move on to IAM configuration&lt;/p&gt;

&lt;h3 id="CreateNewIDP"&gt;Create new IAM SAML Identity Provider&lt;/h3&gt;

&lt;p&gt;First we need to create a new Identity Provider in IAM for the Application we just created.&lt;/p&gt;

&lt;ol id="block-df7dc35d-228e-45aa-a2aa-1ef9ad72de44"&gt;
&lt;li&gt;If you are not already signed in, sign in to the AWS Management Console in your Management account&lt;/li&gt;
&lt;li&gt;Navigate to the IAM service&lt;/li&gt;
&lt;li&gt;On the left hand navigation bar, click &lt;strong&gt;Identity Providers&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click the blue button &lt;strong&gt;Add Provider&lt;/strong&gt; on the upper right &lt;/li&gt;
&lt;li&gt;On the resulting screen, leave the provider type as &lt;strong&gt;SAML&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter a unique provider name&lt;/li&gt;
&lt;li&gt;Click the&lt;strong&gt; Choose file&lt;/strong&gt; button and upload the metadata file you downloaded in the earlier section&lt;/li&gt;
&lt;li&gt;Add tags as appropriate and click the blue &lt;strong&gt;Add Provider &lt;/strong&gt;button&lt;/li&gt;
&lt;/ol&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%2F4oju4g6nieyyrrw2dlnz.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%2F4oju4g6nieyyrrw2dlnz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we need to implement a SAML Federation IAM role.  The purpose of this role is to establish a trust relationship between IAM and AWS SSO.  To implement, navigate to the &lt;strong&gt;Roles&lt;/strong&gt; section of IAM and click &lt;strong&gt;Create Role&lt;/strong&gt;.  I will walk you through each step of the Create Role wizard.&lt;/p&gt;

&lt;h4&gt;Step 1 - Select Trusted Entity&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Click the Radio button next to "SAML 2.0 federation"&lt;/li&gt;
&lt;li&gt;From the SAML 2.0 Provider drop down, select the IDP you just created&lt;/li&gt;
&lt;li&gt;Select the radio button for "Allow programmatic and AWS Management Console access"&lt;/li&gt;
&lt;li&gt;Click the blue &lt;strong&gt;Next&lt;/strong&gt; button&lt;/li&gt;
&lt;/ol&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%2Fqzmre7bro864cfdh0a6u.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%2Fqzmre7bro864cfdh0a6u.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Step 2 - Add permissions&lt;/h4&gt;

&lt;p&gt;Now we need to attach a policy to this new role.  We will be building a custom policy so click the &lt;strong&gt;Create Policy&lt;/strong&gt; button on the upper right.  A new window will pop open for you to create a policy, click the JSON tab and enter a policy in JSON format using the following as a guide, replacing the account ID with your own:&lt;/p&gt;

&lt;pre&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "quicksight:CreateReader"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:quicksight::&lt;em&gt;accountid&lt;/em&gt;:user/${aws:userid}"
        }
    ]
}&lt;/pre&gt;

&lt;p&gt;Note that for my purposes, I only want SSO users to have the QuickSightReader permission, so my policy only includes that permission.   This &lt;a href="https://docs.aws.amazon.com/quicksight/latest/user/external-identity-providers-setting-up-saml.html#external-identity-providers-grantperms" rel="noreferrer noopener"&gt;QuickSight documentation page&lt;/a&gt; provides details on additional permissions you can grant if desired.&lt;/p&gt;

&lt;p&gt;Give your policy a name and then click the blue &lt;strong&gt;Create Policy&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Go back to the window where you were creating the new Role, click refresh on the policy screen, and then select the new policy you just created and click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;Step 3 - Name, review and create&lt;/h4&gt;

&lt;p&gt;Give your role a name, a description and validate the trust and permissions are correct.  Add tags as needed and then click the blue &lt;strong&gt;Create role&lt;/strong&gt; button.&lt;/p&gt;

&lt;h3 id="AttributeMapping"&gt;Update Attribute Mapping in AWS SSO&lt;/h3&gt;

&lt;p&gt;With our IDP and IAM role created, we need to go back to AWS Single Sign On and update our QuickSight application with the proper attribute mappings to use the IAM role and IDP.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;While signed in to the AWS Management Console in the Organizations Management account, navigate back to the AWS Single Sign-On (SSO) service&lt;/li&gt;
&lt;li&gt;On the left hand menu, select &lt;strong&gt;Applications&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click on the Amazon QuickSight application you previously created&lt;/li&gt;
&lt;li&gt;Choose the &lt;strong&gt;Attribute Mappings&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add new attribute mapping&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the first field, enter `https://aws.amazon.com/SAML/Attributes/Role`&lt;/li&gt;
&lt;li&gt;In the Value field, enter &lt;strong&gt;both&lt;/strong&gt; the ARNs for the IAM role and the SAML provider &lt;strong&gt;separated with a comma&lt;/strong&gt;, e.g. `arn:aws:iam::&lt;strong&gt;ACCOUNTID&lt;/strong&gt;:role/&lt;strong&gt;ROLENAME&lt;/strong&gt;,arn:aws:iam::&lt;strong&gt;ACCOUNTID&lt;/strong&gt;:saml-provider/&lt;strong&gt;SAMLPROVIDERNAME`&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Leave Format as unspecified&lt;/li&gt;
&lt;li&gt;Click the blue &lt;strong&gt;Save Changes&lt;/strong&gt; button&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id="AssignUsers"&gt;Assign Users to Application&lt;/h3&gt;

&lt;p&gt;With all the back-end setup work completed, we can now assign users to our QuickSight application!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;While signed in to the AWS Management Console in the Organizations Management account, navigate back to the AWS Single Sign-On (SSO) service&lt;/li&gt;
&lt;li&gt;On the left hand menu, select &lt;strong&gt;Applications&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click on the Amazon QuickSight application you previously created&lt;/li&gt;
&lt;li&gt;Choose the &lt;strong&gt;Assigned Users&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt;Click the blue &lt;strong&gt;Assign users&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;In the assign Users screen you can toggle between Users and Groups, select the User or Group you wish to assign to the Application and then click the blue &lt;strong&gt;Assign users&lt;/strong&gt; button &lt;/li&gt;
&lt;/ol&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%2Feixngswztemm8xs3nhqu.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%2Feixngswztemm8xs3nhqu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NOTE: I'd recommend you create a new AWS SSO group for this purpose and assign the application to the group.  That way when you onboard more users you can just add them to the group.   &lt;/p&gt;

&lt;h2&gt;Test!&lt;/h2&gt;

&lt;p&gt;With all the configuration out of the way, you can now test the SSO configuration.  Login to your AWS SSO portal using the user you assigned to the QuickSight Application.   In addition to the AWS Account application they should now see an application button for Amazon QuickSight.&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%2Fpvw2ynvrzbqiyhsaei1y.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%2Fpvw2ynvrzbqiyhsaei1y.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking on the Amazon QuickSight button will launch QuickSight in a new window and the user will be walked through the first time login screen.  Note when they initially login they will not have any dashboards visible until an admin assigns them.  I will cover this topic in my next post in this series so stay tuned!&lt;/p&gt;

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

&lt;p&gt;In this article I gave you a quick introduction to the QuickSight Cost Intelligence dashboards, and walked you through how you can connect AWS Single Sign-on to QuickSight so that users can use their corporate credentials to access QuickSight directly.  In future articles in this series I will be covering customizing and publishing dashboards to users, as well as how to implement QuickSight Groups and use row level security in QuickSight to filter access for different account owners.  I hope you found this information useful, and please feel free to send me feedback or ask questions in the comments below.&lt;/p&gt;

&lt;p&gt;Finally, I have to give a huge thanks to Jenny Oshima, my AWS Technical Account Manager, as well as Aaron Edell, GTM for Customer Cloud Intelligence for AWS who helped me out a ton during the implementation phase of this project.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/mt/visualize-and-gain-insights-into-your-aws-cost-and-usage-with-cloud-intelligence-dashboards-using-amazon-quicksight/" rel="noreferrer noopener"&gt;AWS Blog - Visualize and gain insights into your AWS cost and usage with Cloud Intelligence Dashboards and CUDOS using Amazon QuickSight&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="noreferrer noopener" href="https://aws.amazon.com/blogs/aws-cloud-financial-management/a-detailed-overview-of-the-cost-intelligence-dashboard/"&gt;AWS Blog - A Detailed Overview of the Cost Intelligence Dashboard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wellarchitectedlabs.com/cost/200_labs/200_cloud_intelligence/" rel="noreferrer noopener"&gt;Well Architected Labs - Cloud Intelligence Dashboards&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/aws-samples/aws-cudos-framework-deployment" rel="noreferrer noopener"&gt;Github - CUDOS Deployment Framework&lt;/a&gt;&lt;/p&gt;

</description>
      <category>finops</category>
      <category>cloudcostmanagement</category>
    </item>
    <item>
      <title>Automated Enterprise Deployment of AWS Config</title>
      <dc:creator>Mike Graff</dc:creator>
      <pubDate>Thu, 14 Apr 2022 15:35:48 +0000</pubDate>
      <link>https://dev.to/aws-builders/automated-enterprise-deployment-of-aws-config-19dp</link>
      <guid>https://dev.to/aws-builders/automated-enterprise-deployment-of-aws-config-19dp</guid>
      <description>&lt;h3&gt;AWS Config - powerful tool but a deployment headache&lt;/h3&gt;

&lt;p&gt;Seasoned users of AWS will be familiar with the &lt;a href="https://aws.amazon.com/config/"&gt;AWS Config&lt;/a&gt; service.  Config is a powerful tool that lets you continuously monitor and record the configuration of AWS resources in your account.   Using Config, you can easily see changes to configuration of a given AWS resource on a timeline, see who made a given configuration change, and see relationships between resources in your account.   Config also offers a powerful feature that allows you to setup governance rules to alert you when resources don't match your desired guidelines.&lt;/p&gt;

&lt;p&gt;AWS recommends setting up AWS Config in each of your AWS account(s) as a best practice.  Experienced users of Config know that this can rapidly become a cumbersome process if you have more than a few AWS accounts.   AWS Config is a regional service which means you need to enable it in every region in which you operate.  This can be a mind-numbing process using the AWS Console, and even using AWS CLI it is a complicated multi-step affair:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an S3 bucket&lt;/li&gt;
&lt;li&gt;Create an IAM Role&lt;/li&gt;
&lt;li&gt;Create an SNS topic&lt;/li&gt;
&lt;li&gt;Create configuration recorder&lt;/li&gt;
&lt;li&gt;Create a delivery channel&lt;/li&gt;
&lt;li&gt;Start the Configuration recorder&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now imagine doing this doing this twenty times (once for each region) across 150 AWS accounts and I think you can begin to imagine the pain and suffering involved.&lt;/p&gt;

&lt;p&gt;For admins of large multi-account environments that live within an AWS Organization, I'm happy to share there is a much easier way to deploy Config across all accounts and regions at once and for new accounts in your organization to have Config enabled automatically.  The magic?  CloudFormation StackSets to the rescue!&lt;/p&gt;

&lt;h3&gt;The Solution&lt;/h3&gt;

&lt;p&gt;In this solution, we will be setting up an AWS Organization wide Config service deployment, with all configuration recorder data being logged to a single centralized Amazon S3 bucket.   Config service will be enabled in every account and region leveraging &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html"&gt;CloudFormation StackSets&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_GyM8Nfc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kt5f3q99mbak86dqyaq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_GyM8Nfc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kt5f3q99mbak86dqyaq.png" alt="AWS Config Org Deployment Architecture" width="880" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Prerequisites&lt;/h3&gt;

&lt;p&gt;In order to deploy this solution successfully there are a few requirements that must be taken care of first.&lt;/p&gt;

&lt;h5&gt;AWS Organizations&lt;/h5&gt;

&lt;p&gt;In order to leverage AWS StackSets, your AWS accounts must be members of an AWS Organization.  Your accounts should be organized into one or more Organizational Units (OUs).  I also recommend creating a "Testing" OU where you can try out your StackSet deployments on a test account before unleashing them on all accounts in your organization.   In addition your AWS Organization should have &lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_support-all-features.html"&gt;all features enabled&lt;/a&gt;, not just consolidated billing.&lt;/p&gt;

&lt;h5&gt;Enable Stack Sets Trusted Access&lt;/h5&gt;

&lt;p&gt;We will be creating a StackSet with "service-managed" permissions.  I highly recommend this option because with service-managed permissions, you do not need to worry about creating IAM roles in each account you will be deploying in...StackSets will take care of that for you automatically.  &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-concepts.html#stacksets-concepts-stackset-permission-models"&gt;This AWS documentation page&lt;/a&gt; provides more details on the different permissions models for StackSets deployments.  Before you can start deploying StackSets with service-managed permissions, you must &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-orgs-enable-trusted-access.html"&gt;enabled trusted access with AWS Organizations&lt;/a&gt;.   There are multiple ways to enable this, but the simplest way to do so is via the CloudFormation console.   &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign into your Organizations management account as a user with Administrator Access&lt;/li&gt;
&lt;li&gt;Navigate to the AWS CloudFormation console&lt;/li&gt;
&lt;li&gt;In the left-side navigation pane, choose &lt;strong&gt;StackSets&lt;/strong&gt;.  If trusted access is not currently enabled, a banner will appear at the top of the page that prompts you to enable trusted access.&lt;/li&gt;
&lt;li&gt;Click the Enable trusted access button to enable this feature.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PSf33V1Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/exj5a5mjyn0tsm37ivhe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PSf33V1Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/exj5a5mjyn0tsm37ivhe.png" alt="Enable Trusted Access button" width="880" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Trusted access is successfully enabled when the following green banner displays:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9TYMeCbR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3xhv3u0iy3bh6661dey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9TYMeCbR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3xhv3u0iy3bh6661dey.png" alt="Successfully enabled trusted access" width="880" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Centralized S3 Bucket&lt;/h5&gt;

&lt;p&gt;Rather than deploying an S3 bucket for each linked member account, this architecture relies on a single S3 bucket that all accounts write their logs to.  If you are managing a large multi-account environment, you probably already have a centralized logging account, and this is where you should place this new bucket for config logging.  Create an appropriately named S3 bucket in your logging account and ensure that the Block Public Access settings are enabled for the bucket.  Then apply a bucket policy on the bucket that allows every account in the organization to access the bucket as well as the AWS Config service to access the bucket. &lt;/p&gt;

&lt;p&gt;Below is a example bucket policy that demonstrates this configuration by leveraging the &lt;strong&gt;aws:PrincipalOrgID&lt;/strong&gt; conditional to allow access from every account in the org and then uses Principal "Service": "config.amazonaws.com" to allow AWS Config the access it needs to the bucket.&lt;/p&gt;



&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2008-10-17",
    "Id": "Policy1357935677554",
    "Statement": [
        {
            "Sid": "ListBucketAccess",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-config-bucket",
                "arn:aws:s3:::my-config-bucket/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "o-1111111111"
                }
            }
        },
        {
            "Sid": "PutObjectAccess",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::my-config-bucket/AWSLogs/*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "o-1111111111"
                }
            }
        },
        {
            "Sid": "AWSConfigBucketPermissionsCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "config.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::my-config-bucket"
        },
        {
            "Sid": "AWSConfigBucketExistenceCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "config.amazonaws.com"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::my-config-bucket"
        },
        {
            "Sid": "AWSConfigBucketDelivery",
            "Effect": "Allow",
            "Principal": {
                "Service": "config.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::my-config-bucket/AWSLogs/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;With these prerequisites out of the way, we can now proceed with deployment of the solution using CloudFormation StackSets.&lt;/p&gt;

&lt;h3&gt;StackSet Deployment&lt;/h3&gt;

&lt;p&gt;StackSets are created in the AWS Organizations management account, using the same CloudFormation template concept as a normal CloudFormation stack.   A StackSet is created and targeted at one or more Organizational Units (OUs), and CloudFormation deploys a Stack in each targeted account and region.&lt;/p&gt;

&lt;p&gt;For this deployment, we will be leveraging a pre-built template from AWS, making our job easier.   Follow this procedure to create a new CloudFormation StackSet in your AWS Organizations Management account&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log into the AWS Console in your Management account with a user that has Administrator Access permissions&lt;/li&gt;
&lt;li&gt;Navigate to the CloudFormation service console&lt;/li&gt;
&lt;li&gt;In the left-side navigation pane, choose &lt;strong&gt;StackSets&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click the orange &lt;strong&gt;Create StackSet&lt;/strong&gt; button to start the new StackSet deployment workflow&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Below I will walk you through each step of the deployment workflow&lt;/p&gt;

&lt;h5&gt;Step 1: Choose a template&lt;/h5&gt;

&lt;p&gt;Ensure &lt;strong&gt;Service-managed permissions&lt;/strong&gt; is selected and select the option to Use a sample template.  From the Sample templates drop down, select the option "&lt;strong&gt;Enable AWS Config with central logging&lt;/strong&gt;". &lt;/p&gt;

&lt;p&gt;Then click the orange &lt;strong&gt;Next&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v7qZrjJM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/669xxi4tr84e02kcpnvm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v7qZrjJM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/669xxi4tr84e02kcpnvm.png" alt="StackSet Deploy Step 1" width="880" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Step 2: Specify Stack Set Details&lt;/h5&gt;

&lt;p&gt;Give your StackSet a meaningful name.  You can leave all Parameters as default, with the following exception.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Under Central S3 bucket, enter the Name of the S3 bucket you created to store your config logs.   NOTE: do not enter an ARN here, just the name of the bucket&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Optionally, you can modify the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can choose to include global resource types by changing that setting to true.&lt;/li&gt;
&lt;li&gt;You can modify the frequency of with which AWS config delivers configuration snapshots by modifying the Snapshot delivery frequency.&lt;/li&gt;
&lt;li&gt;You can specify an email address for AWS Config notifications in the Notification Email field.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When finished configuring options, click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9qzHte7x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0sluedssuooa8k7ieyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9qzHte7x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0sluedssuooa8k7ieyw.png" alt="StackSet Deploy Step 2" width="880" height="1018"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Step 3: Configure Stack Set Options&lt;/h5&gt;

&lt;p&gt;Apply any tags that you want for your StackSet in this screen.  You can leave Managed Execution set to Inactive or change it to Active if you want CloudFormation to perform non-conflicting operations concurrently.   When finished click the orange Next button.&lt;/p&gt;

&lt;h5&gt;Step 4: Set deployment options&lt;/h5&gt;

&lt;p&gt;Leave the deployment option set to Deploy new stacks.  &lt;/p&gt;

&lt;p&gt;For deployment targets, I always recommend starting out with a testing OU when deploying new StackSets to make sure there are no issues before targeting the entire organization.   Select the radio button for Deploy to organizational units and enter the AWS OU ID in the text box.  (You can retrieve OU IDs from the AWS Organizations console).   &lt;/p&gt;

&lt;p&gt;Leave Automatic deployment set to enabled, in this way if a new account is added to the OU a new stack is automatically pushed to that account. Account removal behavior should be set to delete stacks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xlUUCBfJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xs20gt0neroulu83xieq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xlUUCBfJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xs20gt0neroulu83xieq.png" alt="StackSet Deploy Step 3" width="880" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Specify Regions&lt;/strong&gt; section, you can choose the regions you want to target from the drop down menu or click the Add all regions. Note that you should only target regions that are enabled in your target accounts, and those regions must also be enabled in your management account.  See &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-prereqs.html#stacksets-opt-in-regions"&gt;this note from AWS&lt;/a&gt; for more details on this.&lt;/p&gt;

&lt;p&gt;Finally for &lt;strong&gt;Deployment options&lt;/strong&gt;, choose the Maximum concurrent accounts you wish the stack to be deployed to at once.  You can leave this at 1 or set a higher value.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;Fault tolerance&lt;/strong&gt;, I recommend setting this a value higher than 0, otherwise your whole deployment will stop if a single account fails in a single region.  I typically set this value to 2 or 3 so that a single error will not cause the entire StackSet deployment to fail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Region concurrency&lt;/strong&gt; controls how many regions will be deployed at the same time for a given account.  For faster operations, set this to Parallel.&lt;/p&gt;

&lt;p&gt;When finished configuring options, click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LFmBV48M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r84rpk830g11zbf97k0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LFmBV48M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r84rpk830g11zbf97k0g.png" alt="StackSet Deploy Step 4" width="880" height="1300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Step 5: Review&lt;/h5&gt;

&lt;p&gt;Review all your settings to ensure they are accurate, then click the orange Submit button.  You will be taken to the Operations tab for the new StackSet you just deployed, and it should have a status of Running&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1NdXIyOc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72ohoq4nwdhfwxw3hp3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1NdXIyOc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72ohoq4nwdhfwxw3hp3o.png" alt="Stack Set Operations Screen showing job status" width="880" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If all goes well, the Operation status will change from Running to Succeeded, indicating the stack was deployed successfully in all targeted accounts and regions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kf7rxef_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfggxcvzemziarly6o1o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kf7rxef_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfggxcvzemziarly6o1o.png" alt="Stack Set Operation Completed Successfully" width="880" height="62"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can then click on the Stack Instances tab to see the individual CloudFormation stack deployments in each account and region.  You can also use the Stack Instances tab in the case of a deployment failure to see what went wrong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N8ak3uHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcdzjmk7s10kxlw5fr0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N8ak3uHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcdzjmk7s10kxlw5fr0g.png" alt="Stack Set Instances screen showing all deployed stacks" width="880" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Conclusion &amp;amp; Next Steps&lt;/h3&gt;

&lt;p&gt;To wrap up, in this post I've shown you how you can automatically deploy the AWS Config service across all regions for all AWS accounts in your AWS Organization, and have all configuration recorder data stored in a centralized S3 bucket.  By deploying this architecture you will have the ability to assess, audit and evaluate the configuration of all AWS resources in your account(s), and track changes to those resources over time.  In addition with this service enabled across your accounts, you can then implement additional governance across your AWS environments by leveraging &lt;a href="https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config.html" rel="noreferrer noopener"&gt;AWS Config Rules&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some of you may have already deployed AWS Config across your accounts in a decentralized fashion, and may be wondering how to migrate to this centralized architecture.  Stay tuned as I will be covering that in my next post in this series.&lt;/p&gt;

&lt;p&gt;I hope you've found this content useful.  If you have feedback or suggestions on how this content could be improved, please leave a comment below.&lt;/p&gt;

&lt;h3&gt;Learn More&lt;/h3&gt;

&lt;p&gt;If you want to learn more about AWS Config service here are some links for more research:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a rel="noreferrer noopener" href="https://docs.aws.amazon.com/config/latest/developerguide/WhatIsConfig.html"&gt;AWS Config Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/config/faq/" rel="noreferrer noopener"&gt;AWS Config FAQs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a rel="noreferrer noopener" href="https://github.com/awslabs/aws-config-rdk"&gt;AWS Config Rules Development Kit&lt;/a&gt; @ Github&lt;/li&gt;
&lt;li&gt;&lt;a rel="noreferrer noopener" href="https://www.youtube.com/watch?v=kErRv4YB_T4"&gt;AWS re:Invent 2018: Centrally Monitoring Resource Configuration &amp;amp; Compliance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a rel="noreferrer noopener" href="https://www.youtube.com/watch?v=JXwEMipnY-o"&gt;Monitoring and Remediating Non-Compliant Resources with AWS Config&lt;/a&gt; @ AWS YouTube&lt;/li&gt;
&lt;li&gt;&lt;a rel="noreferrer noopener" href="https://aws.amazon.com/blogs/mt/visualizing-aws-config-data-using-amazon-athena-and-amazon-quicksight/"&gt;Visualizing AWS Config data using Amazon Athena and Amazon QuickSight&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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