Wilson Mar bio photo

Wilson Mar


Calendar YouTube Github


Define allow/deny privileges to actions by users, groups, roles by attaching to each identity a conditional policy file constructed for each of 250+ AWS services.

US (English)   Norsk (Norwegian)   Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Estonian   اَلْعَرَبِيَّةُ (Egypt Arabic)   Napali   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean


This tutorial is for AWS learners and corporate Administators who setup root accounts linked to credit cards.

NOTE: Content here are my personal opinions, and not intended to represent any employer (past or present). “PROTIP:” here highlight information I haven’t seen elsewhere on the internet because it is hard-won, little-know but significant facts based on my personal research and experience.

My GitHub Starter

PROTIP: Here you are guided to automate enterprise-scale IAM setup accounts, with security features enabled to block hackers making you pay for runaway bills (to mine their Bitcoin, etc.).

  1. Use my shell script to clone GitHub a set of my DevSecOps automation assets:

    A. Shell script to download GitHub and install all utiities and files required. This is also run to ensure that the latest versions of all utilities are installed (for best security)

    B. Data files used to create (en masse) sample users in departments, projects, and with other attributes for several types of enterprise with varying spans of control and layers of management.

    C. Role charts (by job function) showing responsibilities by (actionable) role, generated from the above data

    D. Automation (Terraform files, etc.) to create resources (Graph databases, etc.)

    E. Python programs to manage data (users, groups, roles, GitHub, within a hierachy of division, projects, etc.)

    F. Python program to create animated lines, histograms, and other analytics about the sample data

    G. az-info.sh CLI script to display status of resource within the current AWS account

    H. CI/CD (Jenkins) automation to run the above to automatically to scan code of various types (Terraform, Python, Shell scripts, etc.) then create resources and IAM policies that implement segmentation.

    I. Functional and capacity regression tests of sample applications in the resources created

Basic Policy JSON

Because AWS denies all actions by default, a new user has no access to any AWS resources until an IAM policy is attached to that user.

Here is a sample bare-bones JSON IAM policy statement to allow the identity to List All buckets in S3:

     "Version": "2012-10-17",
    Statement = [
        Action = [
        Effect   = "Allow"
        Resource = "*"
  • Action defines the AWS service (s3) and specific action (such as Describe, List, Create, Delete, etc.).

    PROTIP: The AWS Actions Table defines thousands of Actions for each of its hundreds of services:

Optionally, add:

  • Sid (Statement Identifier) for the statement. But it’s up to you to keep them unique.
  • Principal to represent resource-based policies. Not required in case of IAM permission policies.
  • Condition that must be fulfilled for the statement to apply.

BTW The above is one of six types of policies AWS supports:

  • Identity-based policies (the focus of this article)

    Identity-based policies govern what actions an identity (User, Group, Role) can perform on which resources and under what conditions.

  • Resource-based policies
  • Permissions boundaries

  • Organizations SCPs (Service Control Policies)
  • ACLs (Access Control Lists)
  • Session policies


Security Topics

https://cloudonaut.io/aws-security-primer includes a thorough mind-map of concepts related to IAM and AWS Security: aws-iam-cloudnaut-1937x1317.png

Cloudonaut.io is maintained (from Stuttgart, Germany) by Michael Wittix (@hellomichibye) and his brother Andreas Wittix are of https://widdix.net. They published video courses with O’Reilly, Manning, Pluralsight, and A Cloud Guru. They maintain repositories at https://github.com/widdix about IAM:

He wrote How to become an AWS expert

Shared Responsibility

AWS’s “shared responsibility model” means what’s of the cloud. You (the admin) secures what’s in the cloud. See this sung and musical by Kate Turchin, a Cloud Security Advocate:

“We must all do our part… so MFA your IAM and rotate all your keys…”


Two tenants of the PDF: “Zero Trust” security strategy is to assume compromise and segmentation.

PROTIP: For segmentation, assign a different AWS account to each business unit, application, or environment. to This makes it unnecessary to share credentials to get work done and the lack of accountability that comes with it.

To avoid credentials sitting around to be stolen, HashiCorp Vault works with databases to dynamically create a new temporary account with new passwords for every occasional use.

PROTIP: Also for segmentation, rather than using the same account for all actions, create different accounts for different types of actions. For example, create one account to create backup files and another separate account that can delete those files.

Global Admin services

AWS has created several services that span many user accounts and organizations for Global Admins:

  • Control Tower

  • Billing

  • amazon-identitycenter.svgIAM Identity Center (successor to AWS Single Sign-On) is used to centrally manage workforce access to multiple AWS accounts and cloud applications. It is used to provide users with single sign-on access from one place to all their assigned accounts and applications.

Control Tower


  • https://us-east-2.console.aws.amazon.com/sso/home?region=us-east-2

AWS Control Tower is a free service that provides a “landing zone” (using AWS Organizations) for the master account to setup and manage multiple AWS accounts and teams.

It also adds visibility into compliance status quickly.

Guardrails to setup data residency preventive and detective controls

Group policies -> Add Users

VIDEO: LAB: Here is a step-by-step tutorial to use the AWS Management Console GUI to create a group policy for Lambda, S3 Bucket, DynamoDB. Then attach users to the group.

  1. Create Policy
  2. Create User Group
  3. Attach Users to Group (Attaching IAM policy directly to the IAM user is not a good practice)


  1. Obtain an account and password to login to the AWS Mangement Console.
  2. Setup MFA. Record the AWS account number (12 digits) and the ARN (Amazon Resource Name) of the MFA device.

  3. Go to IAM (or pull down a browser bookmark)

    Least privilege strategy

  4. PROTIP: Design the permissions you need for each service. For example: Lambda, S3, DynamoDB). This is so you’re not giving out “FullAccess” but use a more granular least privilege approach to limit scope of access.

    For example, only Administrators can create accounts and delete critical resources.

    Consider AWS SCPs (Service Control Policies) for AWS Organizations (@AWSsecurityinfo)

    Create Policy

    Among attributes in a sample HashiCorp HCL to create IAM policy for use in Terraform, which is a declarative language to define infrastructure as code.


    Terraform’s “jsonencode” function converts a Terraform expression’s result to valid IAM JSON Policy syntax.

    resource "aws_iam_policy" "policy" {
      name        = "test_policy"
      path        = "/"
      description = "My test policy"
      policy = jsonencode({
     Version = "2012-10-17"
     Statement = [
         Action = [
         Effect   = "Allow"
         Resource = "*"


    Embedded Heredoc string

    Alternatively, the Heredoc string defined between «EOT and EOT embeds a string within a Terraform expression. An example:

    resource "aws_iam_policy" "policy" {
      name        = "${random_pet.pet_name.id}-policy"
      description = "My test policy"

policy = «EOT { “Version”: “2012-10-17”, “Statement”: [ { “Action”: [ “s3:ListAllMyBuckets” ], “Effect”: “Allow”, “Resource”: “” }, { “Action”: [ “s3:” ], “Effect”: “Allow”, “Resource”: “${aws_s3_bucket.bucket.arn}” } ]

} EOT } </pre>

  1. Click “Policies” on the left menu.
  2. Click “Create Policy” (blue icon).
  3. Click “Import managed policy”.

    This is a misnomer. It should really be “Create policy to import into IAM for it to manage”.

  4. Repeat for each service:

    1. Type the service name in the field labeled “Filter policy”. Note you don’t have to press Enter.
    2. Click the dot associated with “FullAccess”.
    3. Click “Import”.

  5. Click “JSON” tab.

    REFERENCE: Policies Grammar

    • Each statement has a “Sid” (Statement ID) label unique within the JSON file.
    • The Effect is Allow or Deny.

    Actions in each AWS Service

    • Action: “iam:PassRole” for Lambda
    • Action: “iam:CreateServiceLinkedRole” for DynamoDB
    • Action: [ cloudwatch & logs ]
    • Action: [ … ]

    lists for Each AWS service its actions, resources, and condition context keys for use in IAM policies.

    https://iam.cloudonaut.io provides a Complete AWS IAM Reference (via https://github.com/widdix/complete-aws-iam-reference)

    Policy Variables and Naming Conventions

    Create a reusable set of IAM policies to restrict access not only between project and application admins and users, but also between different development, stage, and production users.

    BLOG: See Naming Conventions on examples of policy variables, such as:

        "Condition": {
         "StringEquals": {
             "aws:RequestTag/access-project": "${aws:PrincipalTag/access-project}",
             "aws:RequestTag/access-application": "${aws:PrincipalTag/access-application}",
             "aws:RequestTag/access-environment": [ "dev", "stg", "prd" ],   
             "aws:RequestTag/cost-center": "${aws:PrincipalTag/cost-center}"

    Notice the use of 3-character environment names so a list of variable names align vertically.

    Attribute-based access control (ABAC)

    ABAC is an authorization strategy that defines permissions based on attributes defined by Tags attached to IAM resources, including IAM entities (users or roles) and to AWS resources. ABAC policies are more flexible than traditional AWS policies, which require you to list each individual resource. Use of ABAC allow resources to grow with fewer changes to AWS policies.

  6. PROTIP: Look at the “Character count” at the lower-left corner.

    CAUTION: REMEMBER: Each JSON document has a limit of 6,144 bytes.

    Tag Naming Conventions

    PDF: AWS Tagging Best Practices

  7. Click “Next:Tags”.

    Tags are not required by AWS, but most enterprises require them for accounting to cost centers, etc. and so likely have Terraform Enterprise Sentinel policies to stop provisioning unless they are defined.

    PROTIP: Tags are also useful for troubleshooting in that they enable you to filter logs.

    Adopt a Standardized Approach for Tag Names

    PROTIP: Name tags using a prefix identifying the organization name or abbreviated name, all lowercase, with hyphens separating words. Examples:

    • anycompany:cost-center to identify the internal Cost Center code
    • anycompany:environment-type to identify whether the environment is development, test, or production
    • anycompany:application-id to identify the application the resource was created for

  8. Click “Review” (policy) for a Summary to each service Access Level to Resource scope.

    “Least privilege”?

    Policy Naming Conventions

  9. Type a name for the policy.

    There is a LIMIT of 128 characters for each IAM policy name.

    It’s not necessary to include “policy” in the name.

  10. Click “Create Policy”.

    Create User Group

  11. Click “User groups” on the left menu.
  12. Click “Create group” (blue icon).
  13. Type a group name user the field labeled “User group name”.

    PROTIP: Specify the organizational hierarchy such as “division-dept-team”.

  14. Scroll down to attach a policy by clicking the box next to a policy name.

    Attach Users to Group

    NOTE: This is tedious if you have many users. So many automate this.

  15. Click “Users” in the left menu.
  16. Click the box to the left of each user.

  17. OPTIONAL: Click the cog a the upper-left to select columns to display ARN.

  18. Click “Add users”.
  19. Type in a user name.
  20. Select “Programmatic access” (to issue credentials for using CLI) or “AWS Management Conole access” for the website GUI.
  21. Click “Next: Permissions”.
  22. Click “Next: Tags”.
  23. Click “Next: Review”.

    Notice user has “ChangePassword” permissions.

  24. Click “Create user”.

    “You successfully created the users shown below. You can view and download user security credentials. You can also email users instructions for signing in to the AWS Management Console. This is the last time these credentials will be available to download. However, you can create new credentials at any time.

    “Users with AWS Management Console access can sign-in at: https://369074208713.signin.aws.amazon.com/console

  25. Click “Send email” to the user.

    You may need to configure your default email app preferences. To make Gmail your email on MacOS, open Apple’s Mail app. Press apple+, (comma) for the Mail app Preferences. For “Default mail reader:” select “Google Chrome.app”. Click the red x to close the dialog. Press command+Q to close the Mail app.

  26. Click “Close”.

NOTE: Users and roles are both considered a “principals” in AWS (the principal element in role trust policy).


DOC: An AWS role is not associated with standard long-term credentials such as a password or access keys.

Instead of being uniquely associated with a person, a role is intended to be assumable by anyone who needs it.

Assuming a role provides temporary security credentials for a role session. Assigning a role delegates access to users, applications, or services that don’t normally have on-going access to AWS resources.

  1. In the development account, an administrator grants members of the Developers group permission to switch to the role. This is done by granting the Developers group permission to call the AWS Security Token Service (AWS STS) AssumeRole API for the UpdateApp role.

  2. Any IAM user that belongs to the Developers group in the development account can now switch to the UpdateApp role in the production account.

https://www.hudl.com/bits/how-we-stay-sane-with-a-large-aws-infrastructure aws-naming-sample


TCO Calculator for moving

Amazon’s TCO (Total Cost of Ownership) calculator is basically a sales tool to calculate savings from moving to AWS from on-premises servers. It’s online at:

  • Toggle Basic/Advanced for more fields.

  • The instance type is automatically selected based on the memory selected.

3rd-party cloud alternatives

PROTIP: Know that there are competitors for cloud services – not just among the major cloud providers (Amazon, Microsoft, Google), but also among 3rd-party vendors offering niche solutions:

NOTE: Comparison-shop alternatives to services AWS offers:


Estimate bills

  1. PROTIP: Before you dive in, calculate your potential bills by providing usage estimates to the AWS calculator:


    It has a different sheet for each service. Parameters for EC2 include the number of EC2 instances, hosts, EBS volumes, IPs, data transfer, app and network load balancing.

    PROTIP: Remember that there is an additional surcharge for support as a percentage of the whole bill. Rates vary depending on the level of support chosen.

Account administators who hold root accounts linked to credit cards should do the following:

Beware the Hourly Directory service


PROTIP: AWS Directory Services is activated as a pre-requisite for instances, but is not deactivated automatically when those instances are removed, and continue to accrue charges every hour until manually stopped.

PROTIP: To avoid this money-sucing situation, use a script to instantiate and include deactivation of AWS Directory Services as part of that automated script. That or use a corporate shared Directory.

[_] Activate Tags Preferences

  1. Go to https://console.aws.amazon.com/billing/home#/preferences/tags or select your user name at the top black menu and select “My Billing Dashboard”. The Billing dashboard appears. An example:


  2. Select Preferences from the left menu.
  3. Check all the boxes and provide your email address.
  4. Click “Save Preferences”.

    Activate Cost Explorer


    Activate AWS Cost Explorer and 24 hours later, you can graph, visualize, and analyze spend. Filter by specifying date ranges, services, tags, or a combination. Learn more


    Billing Tags

    [_] Estimate bills

  5. PROTIP: Before you dive in, calculate your potential bills by providing usage estimates to the AWS Calculator.

    It has a different sheet for each service. Parameters for EC2 include the number of EC2 instances, hosts, EBS volumes, IPs, data transfer, app and network load balancing.

    PROTIP: Remember that there is an additional surcharge for support as a percentage of the whole bill. Rates vary depending on the level of support chosen.

  6. See the Budget page:



    PROTIP: Pricing for Developer support is the Greater of $29 or 3% of monthly AWS usage, so you may end up paying more if you spend more than $966.67.

    AWS Professional Services

    Over time, the cost per EC2 instance has trended downward* aws-onboarding-cost-ec2-447x288.jpg

    [_] Set Billing alerts

  7. NOTE: Setup billing alerts and notifications

    IAM Policies for this include:

    • Billing
    • AWSPriceListServiceFullAccess

    Define AWS organizations

  8. Define a “Root” user with superpowers on all other AWS Accounts.
  9. Create a separate Master “Root” AWS Account to manage AWS Organisations:

    aws organizations create-account \
    --email valid-email-address \
    --account-name unique descriptive name
  10. Create the hierarchy of individual OUs (Organizational Units).

    <a target=”_blank” href=“aws-org-hierarchy-1828x1066” src=“https://user-images.githubusercontent.com/300046/140323526-7c0eef4c-ba4c-408e-a5e8-f590c98e7d96.png“> <img width=“914” alt=“aws-org-hierarchy-1828x1066” src=“https://user-images.githubusercontent.com/300046/140323526-7c0eef4c-ba4c-408e-a5e8-f590c98e7d96.png“></a>

  11. Assign permissions to view account agreements in AWS Artifact

  12. Click your account name at the black top menu:


  13. Click “My organizations”.

  14. Review the User Guide

    PROTIP: Up to 20 linked AWS accounts can be grouped together for consolidated billing under “AWS Organizations” to take advantage of volume discounts above.

    IAM Policies for this does not include:

    • AWSOrganizationsServiceTrustPolicy (A policy to allow AWS Organizations to share trust with other approved AWS Services for the purpose of simplifying customer configuration)

AWS Services for Security

More on each:

Security Hub

Security Hub Foundational Security Best Practices automates the Top 10 security items to improve in your AWS account

All rules are defined by AWS.

AWS Config

AWS Config logs every change to AWS configurations as a “Configuration Item”, then applies AWS-defined and custom rules to verify whether the change should be allowed.

Amazon GuardDuty

Amazon GuardDuty senses threats

Amazon Detective

Amazon Detective organizes various relationships in a Graph visualization to see how events are interconnected.

Trusted Advisor


AWS Trusted Advisor is a software service (not a consulting offering) which scans your environment to identify recommendations (green checkbox icon) and investigation (orange triangle) that help you follow AWS best practices, to reduce costs, improve performance, improve security.


The Trusted Advisor Dashboard reports the result from scans of your account’s setup based on the Well-Architected Framework.

The policy needed for this:

  • AWSTrustedAdvisorServiceRolePolicy

The AWS CLI command:

aws support describe-trusted-advisor-check-result \
      --check-id eW7HH0l7J9 \
      --query 'result.sort_by(flaggedResources[?status!="ok"],&metadata

To get the check-id:

# region must be us-east-1 as it only when support command works
CHECK_ID=$(aws --region us-east-1 support describe-trusted-advisor-checks --language en --query 'checks[?name==`Service Limits`].{id:id}[0].id' --output text)
echo $CHECK_ID

If you don’t have a premium subscription, this error message appears:

An error occurred (SubscriptionRequiredException) when calling the DescribeTrustedAdvisorCheckResult operation: AWS Premium Support Subscription is required to use this service.

AWS Inspector service


Amazon Inspector Service automates vulnerability assessments of EC2 compute instances.

Enable it to identify ports that are reacheable outside instance VPCs without installing agents. Each assessment template contains rule packages (security checks), defined targes (EC2 instances), time, and notifications.

The first 250 agent-assessments is free during your first 90 days.

Then it’s $0.30 per agent per assessment (agent-assessments) per month.

There are many agents on each machine (apt, yum, and Microsoft Installer).

NOTE: Automation software installs (by Puppet, Chef, Ansible) are not inspected.

CAUTION: What security vulnerabilities an organization has is rather confidential information. So be stingy about granting policies related to Inspector.

Policies for auditors who evaluate security would be:

  • AmazonInspectorReadOnlyAccess (to auditors who evaluate security)
  • SecurityAudit

Policies for those who carry out security assessments:

  • AmazonInspectorFullAccess
  • AmazonInspectorServiceRolePolicy grants Amazon Inspector access to AWS Services needed to perform security assessments.

Related policies include:

  • AWSAccountActivityAccess
  • AWSAccountUsageReportAccess
  • AWSConfigRole
  • AWSResourceGroupsReadOnlyAccess
  • AWSServiceCatalogAdminFullAccess
  • AWSServiceCatalogEndUserFullAccess

  • PowerUserAccess
  • SecretsManagerReadWrite

AWS Shield

AWS Shield provides protection of Distributed Denial of Service (DDoS) attacks which attempts to overwhelm net work and servers within AWS.

Types of attacks include

  • Layer 3 and 4 UDF floods
  • Reflection attacks reflected from a 3rd party to hide the origin of the attack
  • State exhaustion attacks flooding TCP SYN or DNS queries
  • Application-layer floods of HTTP GET or POST calls like normal users

Basic (standard) protections are enabled free on all AWS accounts.

Advanced Shield users get advice from Amazon’s DRT (DDoS Response Team) about

  • Rate-based rules
  • WAF (Web Application Firewall) rules
  • CloudWatch alarms
  • Elastic Load balancing for web apps
  • Elastic IP address for apps in EC2

During an attack, DRT can move your network ACL (Access Control List) to the border of the network. Pricing also includes cost protection against the cost of spikes due to attacks.

The Advanced service provides a global threat environment dashboard.

CLI for costing

At https://medium.com/circuitpeople/aws-cli-with-jq-and-bash-9d54e2eabaf1 Lee Harding answers questions like “What is each service costing me?” Fix the error in this:

aws ce get-cost-and-usage --time-period Start=$(date "+%Y-%m-01"),End=$(date --date="$(date +'%Y-%m-01') + 1 month  - 1 second" -I) --granularity MONTHLY --metrics USAGE_QUANTITY BLENDED_COST  --group-by Type=DIMENSION,Key=SERVICE | jq '[ .ResultsByTime[].Groups[] | select(.Metrics.BlendedCost.Amount > "0") | { (.Keys[0]): .Metrics.BlendedCost } ] | sort_by(.Amount) | add'

Hystax OptScale identifies unused environments; Tracks deploy plans history in Jira, Slack, OptScale UI. Available in Marketplace or SaaS for Kubernetes in public clouds.


  • https://la-tech.co/reusable-iam-polcies/

More on Amazon

This is one of a series on Amazon: