<?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: Matteo Gioioso</title>
    <description>The latest articles on DEV Community by Matteo Gioioso (@matteogioioso).</description>
    <link>https://dev.to/matteogioioso</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%2F497758%2F7362ddda-b890-4763-b88d-f1584b96c2d2.jpeg</url>
      <title>DEV Community: Matteo Gioioso</title>
      <link>https://dev.to/matteogioioso</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matteogioioso"/>
    <language>en</language>
    <item>
      <title>How newcomers can avoid and prevent unwanted charges on their AWS accounts</title>
      <dc:creator>Matteo Gioioso</dc:creator>
      <pubDate>Sun, 01 Aug 2021 08:31:19 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-newcomers-can-avoid-and-prevent-unwanted-charges-on-their-aws-accounts-5425</link>
      <guid>https://dev.to/aws-builders/how-newcomers-can-avoid-and-prevent-unwanted-charges-on-their-aws-accounts-5425</guid>
      <description>&lt;p&gt;Lately I saw many posts and tweets about people racking up moderate to huge bills on AWS without realizing it, a lot of heated discussions, but nothing on how to mitigate those problems. So I have decided to share my experience and my tools to make sure you won't end up owning 80.000$ to AWS. &lt;/p&gt;

&lt;p&gt;Take in consideration that this is a "starter kit", the more your usage grows the more sophisticated methods you will have to adopt, but as a starting point is enough.&lt;/p&gt;

&lt;p&gt;I would say there are two categories when it comes to this matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Costs control&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Costs control
&lt;/h1&gt;

&lt;p&gt;Costs control is just the act of monitoring your current and forecasted bill and make sure it won't exceed your expectation and budget.&lt;br&gt;
We can monitor costs through: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Budget and alerts&lt;/li&gt;
&lt;li&gt;General view of all the resources deployed&lt;/li&gt;
&lt;li&gt;Daily cost notification&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Budget
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The first thing you should do after you sign up for an AWS account is setting up the budget alters&lt;/strong&gt;. If you are lazy but you still want to avoid huge bills, this is the only thing you should do.&lt;br&gt;
Navigate to &lt;a href="https://console.aws.amazon.com/billing/home#/budgets#/home" rel="noopener noreferrer"&gt;AWS budget&lt;/a&gt; with your root account, click on &lt;em&gt;create budget&lt;/em&gt;, select &lt;em&gt;Cost budget&lt;/em&gt;, here you can setup your costs, after that click on &lt;em&gt;configure threshold. &lt;br&gt;
*Here I usually suggest to have two thresholds, one with *Actual&lt;/em&gt; and the other with &lt;em&gt;Forecasted *costs, in this way you can have a visibility on your current and future bill.&lt;br&gt;
**Remember to insert your email under *&lt;/em&gt;&lt;strong&gt;&lt;em&gt;Set up notifications&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2F7hsopb1nqbwn%2F5gXvTpCeCH0blovUyveiCW%2F23d2a27535877a0c5f16556f05428cd7%2Fbudget_threshold.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%2Fimages.ctfassets.net%2F7hsopb1nqbwn%2F5gXvTpCeCH0blovUyveiCW%2F23d2a27535877a0c5f16556f05428cd7%2Fbudget_threshold.png" alt="Budget Threshold"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check &lt;a href="https://www.youtube.com/watch?v=fvz0cphjHjg" rel="noopener noreferrer"&gt;this video tutorial&lt;/a&gt; for more detailed instructions.&lt;/p&gt;
&lt;h3&gt;
  
  
  General view
&lt;/h3&gt;

&lt;p&gt;So, did you spin up a super computer cluster in some obscure region and forgot it about it?&lt;br&gt;
There is a little "trick" to search for all the deployed resources in one place, it is called &lt;a href="https://docs.aws.amazon.com/ARG/" rel="noopener noreferrer"&gt;AWS Resource Groups and tag editor&lt;/a&gt;, probably it is not meant for searching resources, but you can use it for this purpose.&lt;/p&gt;

&lt;p&gt;Navigate to the AWS Console &lt;em&gt;Resource Groups and Tag editor&lt;/em&gt; and from here you can access the &lt;a href="https://console.aws.amazon.com/resource-groups/tag-editor/find-resources?region=us-east-1" rel="noopener noreferrer"&gt;tag editor&lt;/a&gt;, select &lt;em&gt;All regions&lt;/em&gt; and if needed &lt;em&gt;Resources types *(For example: &lt;code&gt;AWS::EC2::Instace&lt;/code&gt;)&lt;/em&gt;, *then press *Search resources. *&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%2Fimages.ctfassets.net%2F7hsopb1nqbwn%2F3HoGasAYMJG9BECFil8lXM%2Ffb92e44439fcf0963cd296da2aa808af%2Fscreenshot-console.aws.amazon.com-2021.06.04-08_20_00.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%2Fimages.ctfassets.net%2F7hsopb1nqbwn%2F3HoGasAYMJG9BECFil8lXM%2Ffb92e44439fcf0963cd296da2aa808af%2Fscreenshot-console.aws.amazon.com-2021.06.04-08_20_00.png" alt="AWS Tag editor console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember this works only at account level, if you have multi-account setup you will have to switch role and repeat the same thing. &lt;/p&gt;
&lt;h3&gt;
  
  
  Daily costs notifications
&lt;/h3&gt;

&lt;p&gt;This is more of an optional step, but sometimes budgets might be not enough, at least in my opinion.&lt;br&gt;
&lt;strong&gt;Budgets, in fact,&lt;/strong&gt; &lt;strong&gt;only alert you when the threshold is breached or it is forecasted to be breached&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;What I usually do, is to have a lambda that gets triggered every day and sends me an SNS notification directly to my inbox with both the forecasted and total current bill; in this way I can check if there have been any abnormality and immediately take action. &lt;/p&gt;

&lt;p&gt;Just recently I have decide to open source it and make it available in the &lt;a href="https://serverlessrepo.aws.amazon.com/applications/ap-southeast-1/164102481775/periodic-costs-notification" rel="noopener noreferrer"&gt;Serverless Application Repository&lt;/a&gt;. To start using it you just need to deploy it into your account, feel free to propose new features  or open a new issue if you find any in the &lt;a href="https://github.com/hirvitek/aws-tools/tree/master/periodicCostsNotification" rel="noopener noreferrer"&gt;github repository&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Security
&lt;/h1&gt;

&lt;p&gt;Security can also have a big impact on costs. &lt;br&gt;
What can happen If a malicious actor can access your account? Well you know, credit card, bitcoin mining, DDOS attacks, etc...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid accidentally pushing credentials to public repository&lt;/li&gt;
&lt;li&gt;Activate Multi-factor authentication&lt;/li&gt;
&lt;li&gt;Periodically rotate passwords and IAM credentials&lt;/li&gt;
&lt;li&gt;Restrict the &lt;code&gt;AdministratorAccess&lt;/code&gt; policy&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Avoid pushing credentials to public repository or share them
&lt;/h3&gt;

&lt;p&gt;This is the scariest thing that can happen to us, if you push credentials to a public repository chances are that in few minutes some bot will discover and grab them. &lt;br&gt;
Let's face it, it might happens, and the remediation is fairly simple.&lt;/p&gt;

&lt;p&gt;One of the tool I am using is &lt;a href="https://github.com/awslabs/git-secrets" rel="noopener noreferrer"&gt;git-secrets by awslabs&lt;/a&gt;.&lt;br&gt;
This tool will install a pre-commit hook that will make your commit fail if it recognize a particular patter, like aws credentials secret keys, in your committed files. &lt;/p&gt;
&lt;h3&gt;
  
  
  Multi-factor authentication
&lt;/h3&gt;

&lt;p&gt;This should be another must and done immediately after sign up. &lt;br&gt;
&lt;strong&gt;You should activate Multi-factor authentication&lt;/strong&gt; for both root account and any IAM user account you create. &lt;br&gt;
You can read more &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;. You can use the Google Authenticator app, however these days I prefer using my &lt;a href="https://www.yubico.com/" rel="noopener noreferrer"&gt;YubiKey&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Passwords rotation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;I highly suggest periodic password rotation.&lt;/strong&gt; You can simply enable password expiration in IAM password policy, in this way you will be forced to periodically change it. Navigate to your &lt;a href="https://console.aws.amazon.com/iam/home#/account_settings" rel="noopener noreferrer"&gt;IAM account settings&lt;/a&gt; and check &lt;em&gt;Password Policy&lt;/em&gt;, check the &lt;em&gt;Enable password expiration&lt;/em&gt; and set the expiration you desire. &lt;br&gt;
Here you can also enforce some password requirements.&lt;/p&gt;
&lt;h3&gt;
  
  
  IAM credentials rotation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;You should periodically rotate your local AWS keys&lt;/strong&gt;.&lt;br&gt;
This is often very overlooked, I saw personal credentials active for years and never deleted or inactivated when a member leaves.&lt;br&gt;
Changing IAM credentials regularly should be a must in any organization, it reduces the impact if the key become compromised. &lt;/p&gt;

&lt;p&gt;The process to rotate the credentials &lt;a href="https://aws.amazon.com/blogs/security/how-to-rotate-access-keys-for-iam-users/" rel="noopener noreferrer"&gt;requires some steps&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a second access keys pair&lt;/li&gt;
&lt;li&gt;Download those keys&lt;/li&gt;
&lt;li&gt;Substitute them from your &lt;code&gt;~/.aws/credentials &lt;/code&gt;file&lt;/li&gt;
&lt;li&gt;Deactivate the previous access keys&lt;/li&gt;
&lt;li&gt;Test that everything is working&lt;/li&gt;
&lt;li&gt;Delete the old keys&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But we can automate this process using the AWS SDK or API.&lt;br&gt;
This is why I have built a small go utility that *&lt;em&gt;helps you rotate local credentials called *&lt;/em&gt;&lt;a href="https://github.com/hirvitek/aws-tools/tree/master/localKeyRotation" rel="noopener noreferrer"&gt;&lt;strong&gt;LocalKeyRotation&lt;/strong&gt;&lt;/a&gt;, not much fantasy in naming, but it does the job.&lt;br&gt;
You can simply run the command or create an &lt;a href="https://man7.org/linux/man-pages/man8/anacron.8.html" rel="noopener noreferrer"&gt;anacron job&lt;/a&gt; to run it periodically. &lt;/p&gt;

&lt;p&gt;Feel free to suggest any feature or open a new issue if you find any.&lt;/p&gt;

&lt;p&gt;Alternatively, if you are using &lt;a href="https://github.com/99designs/aws-vault" rel="noopener noreferrer"&gt;aws-vault&lt;/a&gt;, you can use their &lt;a href="https://github.com/99designs/aws-vault/blob/master/USAGE.md#rotating-credentials" rel="noopener noreferrer"&gt;rotate feature&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Limit IAM permission
&lt;/h3&gt;

&lt;p&gt;*&lt;em&gt;Note: do not create access keys for your root account, instead create a IAM user with limited permission and then create the access keys for that user. *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is a more of an advanced topic, but nonetheless useful.&lt;br&gt;
After you have created your first IAM user, instead of giving him &lt;code&gt;AdministratorAccess&lt;/code&gt;, you can make a custom policy using IAM conditions; you can read more about &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html" rel="noopener noreferrer"&gt;IAM condition here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;One thing I would do is to limit the regions in which you can provision resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Condition": {
                "StringEquals": {
                    "aws:RequestedRegion": "us-east-1"
                }
            }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since a lot of services have regional quotas, for example the base limit of EC2 instances per region is 20, this could somehow tamper the effect of compromised credentials. &lt;br&gt;
You can also limit the type of instances size you can deploy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Condition": {
                "ForAnyValue:StringNotLike": {
                    "ec2:InstanceType": [
                        "*.nano",
                        "*.small",
                        "*.micro"
                    ]
                }
            }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also limit the resources you can work with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
            "Effect": "Allow",
            "Action": [
                "sns:*",
                "s3:*",
                "cloudwatch:*",
                "apigateway:*",
                "lambda:*",
                "dynamodb:*"
            ],
            "Resource": "*"
            }
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way you will make sure nothing else can be deployed other than those services listed in the actions.&lt;/p&gt;

&lt;p&gt;So your custom policy could be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": "us-east-1"
        },
        "ForAnyValue:StringNotLike": {
          "ec2:InstanceType": [
            "*.nano",
            "*.small",
            "*.micro"
          ]
        }
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;I really hope this post can help someone getting started on AWS without getting unwanted nasty surprises, always be vigilant, AWS is not a toy and money is money.&lt;br&gt;
Cheers!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
