AWS
In this tutorial, you will configure IAMbic to manage IAM for an AWS account or multiple accounts in an AWS organization. You will then practice using IAMbic to to create, manipulate, and expire a test group. These are the steps you will complete:
Setup
- Configure IAMbic for AWS
- Import AWS resources
Practice with an IAM role
- Create and Manage an IAM role across multiple AWS accounts
- Create dynamic permissions for your IAM role, which can vary depending on account
- Create temporary permissions for your IAM role (IAMbic will automatically expire these)
- Create temporary access rules for your IAM role (Requires Noq Enterprise)
Practice with Permission Sets and Managed Policies
- Create and Manage an AWS Identity Center (SSO) Permission Set
- Create dynamic permissions for your Permission Set, which can vary depending on account
- Create temporary permissions for your Permission Set (IAMbic will automatically expire these)
- Provide temporary (break-glass) access to your AWS Identity Center Permission Sets
- Create and Manage an IAM Managed Policy
Practice with Service Control Policies (SCPs)
- Import existing Service Control Policies
- Create a Policy
- Attach a Policy to an AWS account, OU, or the root of your AWS Organization
Prerequisites
A local Git repository to store your IAMbic templates (See Getting Started for guidance on setting this up)
Administrative-level access to AWS in order to create and manage IAM identities. This level of access is required to create an IAM identity for the use of IAMbic and also to manage policies associated with it.
These credentials should be configured in the terminal you are using to configure IAMbic.
You should also be aware of how AWS credentials are sourced locally by the Amazon SDKs. This will help debug different scenarios, such as credential prioritization and expiration.
Setup
1. Configure IAMbic for AWS
IAMbic is built around a Hub and Spoke model for managing IAM across multiple AWS accounts. This means that IAMbic creates a hub role in your primary AWS account and assumes a spoke role across each of your accounts to retrieve resources or manage those accounts. You can learn more about this model in our AWS Hub and Spoke Roles documentation.
To configure IAMbic for your AWS accounts, you first need to create a local Git repository and run iambic setup.
During the setup process, you will need to set up an AWS Organization (which loads all accounts for that
organization into your IAMbic configuration file) or that you wish to
manage. Find more specific guidance on how to run iambic setup in our
Install and Configure guide.
If you'd prefer to manually write a configuration, please follow the guidance in our How-To Guides section.
Once you have configured IAMbic, you should see your accounts listed in your repository under
iambic_config.yaml. You can move this file around in your repository if needed. When you run IAMbic,
it will look for the configuration by referencing the template_type, which should be set to NOQ::Core::Config.
2. Import AWS Resources
After configuring IAMbic for AWS, run the iambic import command from the repository you created.
This will read your configuiration, attempt to determine all AWS accounts in your environment,
and attempt to import IAM resources from each account.
In a production environment, automation provided by IAMbic will ensure that Git is continuously
updated with the cloud resources in your production environment. This allows you to monitor the
history of these groups via Git History.
IAMbic will attempt to logically group similar resources into the same template. For example, a
common pattern in naming cookie_cutter IAM roles (such as your engineering role) would be to
prefix the role with the account name that the role resides on. If you had an engineering role
on accounts named prod, test, and staging respectively, the engineering role might be
named prod_engineering, test_engineering, and staging_engineering. This
naming convention makes it easier to identify the correct role when looking at Cloudtrail logs
without having to look up the account ID from the ARN. IAMbic will intelligently group these
roles in the same template. IAMbic will correctly account for different permissions and
access rules based on the account.

Run the following command to import resources from your AWS account(s):
iambic import
Here is a recording of a typical import process:
Once the import has successfully finished, your repository should have a folder structure, with YAML templates nested under each directory structure. It should resemble the following:
$ tree -L 4
├── config
│ └── config.yaml
└── resources
└── aws
├── identity_center
│ └── permission_sets
└── iam
├── managed_policy
│ └── account_1
└── role
└── all_accounts
├── multi_account
├── account_1
├── account_2
└── account_3
You've completed the setup configuration connecting your AWS Organization or accounts to IAMBic. Now you will practice using IAMbic to execute basic IAM management skills.
3 Create and Manage an IAM role across multiple AWS accounts
Now you will create an AWS role across all of the AWS accounts that you've configured. In future steps, we will modify this role to demonstrate some of IAMbic's features. If you've only configured one account, you may still follow this tutorial. It just won't be as exciting :).
A sample multi-account role template is below. It will propagate a role across all known accounts, including new accounts as they are discovered.
Grab your favorite code editor, have your Git repo handy, and let's get to work. First, you'll create a directory for your template if it doesn't already exist. Then you'll edit an appropriately named YAML file for your template.
# Create a directory in your iambic-templates repo
mkdir -p resources/aws/iam/role/all_accounts
# Create and edit an IAMbic template with your favorite editor
code resources/aws/iam/role/all_accounts/iambic_test_role.yaml
Next, we'll create a multi-account role template. An example template is below; it can be used as-is, or modified. Take the contents of this template and write it to the iambic_test_role.yaml file we're editing.
If there are other roles with the role name specified in the template below, they will be overwritten. We've chosen a role name that is specific to IAMbic, so we hope there won't be any conflict.
template_type: NOQ::AWS::IAM::Role
identifier: "{{var.account_name}}_iambic_test_role"
included_accounts:
- "*"
properties:
description: IAMbic test role on {{var.account_name}}
assume_role_policy_document:
statement:
- action: sts:AssumeRole
effect: Deny
principal:
service: ec2.amazonaws.com
inline_policies:
- policy_name: spoke-acct-policy
statement:
- action:
- sqs:GetQueueAttributes
effect: Deny
resource: "arn:aws:sqs:us-east-1:{{var.account_id}}:fakequeue"
managed_policies:
- policy_arn: arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
path: /iambic_test/
permissions_boundary:
policy_arn: arn:aws:iam::aws:policy/AWSDirectConnectReadOnlyAccess
role_name: "{{var.account_name}}_iambic_test_role"
Save the template, and in your terminal, use IAMbic to apply the change.
iambic apply resources/aws/iam/role/all_accounts/iambic_test_role.yaml
If all went according to plan, you should now have a new role across all of the accounts you've defined, or the accounts we've detected in AWS Organizations.
Here is a recording of a typical apply process:
3.1 - Create dynamic IAM role policies that vary per account
Now that we've created an IAM role, let's vary some of the policies based on the accounts at our disposal.
Let's add a new inline policy on only a couple of our accounts. You'll need to uncomment and replace the DEV_ACCOUNT and PROD_ACCOUNT placeholders below with the names or account IDs of some of your accounts.
A possible scenario is your prod account requires managed deletion for compliance reasons. In contrast, you want your developers to be able clean up after themselves in the dev account.
template_type: NOQ::AWS::IAM::Role
identifier: "{{var.account_name}}_iambic_test_role"
included_accounts:
- "*"
properties:
description: IAMbic test role on {{var.account_name}}
assume_role_policy_document:
statement:
- action: sts:AssumeRole
effect: Deny
principal:
service: ec2.amazonaws.com
inline_policies:
- policy_name: s3-access
statement:
- # excluded_accounts: # Include the policy on the role across all accounts, except PROD_ACCOUNT
# - PROD_ACCOUNT
action:
- s3:GetObject
effect: Allow
resource: "arn:aws:s3:::awsexamplebucket1-{{var.account_name}}/*"
- # included_accounts: # Only include the policy statement on DEV_ACCOUNT
# - DEV_ACCOUNT
action:
- s3:DeleteObject
effect: Allow
resource: "arn:aws:s3:::awsexamplebucket1-{{var.account_name}}/*"
- included_accounts:
- "*"
# Include the policy statement on all accounts except AUDITOR_ACCOUNT and SECURITY_ACCOUNT
# excluded_accounts:
# - AUDITOR_ACCOUNT
# - SECURITY_ACCOUNT
action:
- s3:CreateBucket
effect: Allow
resource: "*"
managed_policies:
- policy_arn: arn:aws:iam::aws:policy/job-function/SupportUser
path: /iambic_test/
permissions_boundary:
policy_arn: arn:aws:iam::aws:policy/AmazonS3FullAccess
role_name: "{{var.account_name}}_iambic_test_role"
Save the template, and in your terminal, use IAMbic to apply the change.
iambic apply resources/aws/iam/role/all_accounts/iambic_test_role.yaml
After the command succeeds, you can check on each account via AWS Console to compare the DEV_ACCOUNT and PROD_ACCOUNT contains different inline policies attached to the role (despite managing via a single template).
3.2 - Create Temporary, Expiring IAM Permissions
Now it's time to learn the process of writing temporary permissions that expire after a set period of time. Permissions are only expired if you're running IAMbic continually (IAMbic leverages Amazon Eventbridge Rules to automate this). For the purposes of this tutorial, we will trigger a run locally. In the template below, you'll notice the addition of the expires_at: attribute on different lines. Add them to your file.
Notice that expires_at can be a datetime string, a date, or even "tomorrow", "yesterday", "in N days", etc. This is thanks to the wonderful dateparser library ❤️.
template_type: NOQ::AWS::IAM::Role
identifier: "{{var.account_name}}_iambic_test_role"
included_accounts:
- "*"
expires_at: in 3 days
properties:
description: IAMbic test role on {{var.account_name}}
assume_role_policy_document:
statement:
- action: sts:AssumeRole
effect: Deny
principal:
service: ec2.amazonaws.com
inline_policies:
- policy_name: spoke-acct-policy
statement:
- expires_at: 2021-01-01
# excluded_accounts: # Include the policy on the role across all accounts, except ACCOUNT_A
# - ACCOUNT_A
# action:
# - s3:ListBucket
effect: Deny
resource: "*"
- expires_at: tomorrow
# included_accounts: # Only include the policy statement on ACCOUNT_A
# - ACCOUNT_A
action:
- s3:GetObject
effect: Deny
resource: "*"
- expires_at: in 4 hours
included_accounts: # Include the policy statement on all accounts except ACCOUNT_A and ACCOUNT_B
- "*"
# excluded_accounts:
# - ACCOUNT_A
# - ACCOUNT_B
action:
- s3:ListAllMyBuckets
effect: Deny
resource: "*"
managed_policies:
- policy_arn: arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
path: /iambic_test/
permissions_boundary:
policy_arn: arn:aws:iam::aws:policy/AWSDirectConnectReadOnlyAccess
role_name: "{{var.account_name}}_iambic_test_role"
Now run the apply command.
iambic apply resources/aws/iam/role/all_accounts/iambic_test_role.yaml
Once it has run, you'll notice the changes reflected in the cloud immediately, and the file has been updated to reflect the changes.
3.3 Create temporary access rules
Noq Enterprise is capable of brokering temporary AWS IAM role credentials for end-users and applications. Noq integrates tightly with your single-sign-on provider of choice (almost anything that speaks SAML or OpenID Connect), tightly integrating to provide credentials to your existing groups and users. These credentials can be IP-restricted (either to a static list of IP addresses, such as a list of VPN NAT addresses, or to the requester's IP address). Lastly, the Noq-CLI utility provides a number of developer-friendly methods for managing temporary IAM credentials.
To provide temporary access for a user, add an access_rules section to your YAML. The following is an example access rules stanza that provides access to the user user@example.com, and group group_name. The access rules are applied to the role across all accounts, unless included_accounts or excluded_accounts are specified.
access_rules:
- users:
- user@example.com
- groups:
- group_name
We can further limit these access rules to the role across specific accounts:
access_rules:
- users:
- user@example.com
# included_accounts:
# - ACCOUNT_A
- groups:
- group_name
# included_accounts:
# - ACCOUNT_A
In order to provide temporary access to a role (for break-glass use cases or otherwise), we will add an expires_at flag to the access rules. This will cause the access rules to expire after the specified time. The following example will expire the access rules in 3 days.
access_rules:
- users:
- user@example.com
expires_at: in 3 days
The template below provides a complete example of a role with temporary access rules, and temporary permissions. You will need to modify the account names to match accounts in your environment, and uncomment the sections with expiry dates before applying.
template_type: NOQ::AWS::IAM::Role
identifier: "{{var.account_name}}_iambic_test_role"
included_accounts:
- "*"
# access_rules:
# - users:
# - user@example.com
# expires_at: in 3 days
# included_accounts:
# - ACCOUNT_A
properties:
description: IAMbic test role on {{var.account_name}}
assume_role_policy_document:
statement:
- action: sts:AssumeRole
effect: Deny
principal:
service: ec2.amazonaws.com
inline_policies:
- policy_name: spoke-acct-policy
statement:
- expires_at: 2021-01-01
# excluded_accounts: # Include the policy on the role across all accounts, except ACCOUNT_A
# - ACCOUNT_A
action:
- s3:ListBucket
effect: Deny
resource: "*"
- expires_at: tomorrow
# included_accounts: # Only include the policy statement on ACCOUNT_A
# - ACCOUNT_A
action:
- s3:GetObject
effect: Deny
resource: "*"
- expires_at: in 4 hours
included_accounts: # Include the policy statement on all accounts except ACCOUNT_A and ACCOUNT_B
- "*"
# excluded_accounts:
# - ACCOUNT_A
# - ACCOUNT_B
action:
- "*"
effect: Deny
resource: "*"
managed_policies:
- # included_accounts:
# - ACCOUNT_A
policy_arn: arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
path: /iambic_test/
permissions_boundary:
policy_arn: arn:aws:iam::aws:policy/AWSDirectConnectReadOnlyAccess
role_name: "{{var.account_name}}_iambic_test_role"
Save the template, and in your terminal, use IAMbic to apply the change.
iambic apply resources/aws/iam/role/all_accounts/iambic_test_role.yaml
After applying the changes, the users specified in the access rules will now have access to the role in the Noq platform for 3 days.
4. AWS Identity Center Permission Sets
# Create a directory in your iambic-templates repo
mkdir -p resources/aws/identity_center/permission_set/
# Create and edit an IAMbic template with your favorite editor
code resources/aws/identity_center/permission_set/iambic_test_permission_set.yaml
4.1 - Create a Permission Set
Just like IAM roles, IAMbic can be used to manage permission sets within AWS SSO (Identity Center). Here is an example of a permission set template:
template_type: NOQ::AWS::IdentityCenter::PermissionSet
identifier: iambic_test_permission_set
# included_orgs:
# - o-12345678
properties:
name: iambic_test_permission_set
description: Permission set for testing IAMbic
inline_policy:
statement:
- action:
- "*"
effect: Deny
resource:
- "*"
managed_policies:
- arn: arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
permissions_boundary:
managed_policy_arn: arn:aws:iam::aws:policy/AWSDirectConnectReadOnlyAccess
session_duration: PT1H
Apply the file by running iambic apply.
iambic apply resources/aws/identity_center/permission_set/iambic_test_permission_set.yaml
4.2 Provide access to a permission set
To grant access to a permission set, you can add an access_rules section to the YAML template.
IAMbic does not yet track groups and users natively from AWS Identity Center. If you already use identity provider like Okta or Google Workspace, you can propagate groups and users by integrating AWS Identity Center with external identity providers such as Okta or Google Workspace. IAMbic does provide Okta plugin.
This section specifies which users and groups can access the permission set, on which accounts they have access to, and for how long the access is valid. If the included_accounts field is not specified, the access rule will apply to all accounts configured in AWS Identity Center.
The example provided shows an access
rule that grants access to members of group GROUP_1 on all accounts that start with
ACCOUNT_ except for the ACCOUNT_SENSITIVE account.
access_rules:
- groups:
- GROUP_1
included_accounts:
- ACCOUNT_*
excluded_accounts:
- ACCOUNT_SENSITIVE
The example provided shows an access
rule that grants access to iambic_example_user_1@iambic.org on all accounts that start with
ACCOUNT_ except for the ACCOUNT_SENSITIVE account.
access_rules:
- users:
- iambic_example_user_1@iambic.org
included_accounts:
- ACCOUNT_*
excluded_accounts:
- ACCOUNT_SENSITIVE
The following is an example of the entire permission set template. Revise the users, groups, and account references to match your environment:
template_type: NOQ::AWS::IdentityCenter::PermissionSet
identifier: iambic_test_permission_set
# If we have multiple orgs, we can optionally limit the AWS Organization
# to deploy a permission set to
# included_orgs:
# - o-12345678
# access_rules:
# - groups:
# - GROUP_1
# users:
# - user1@example.com
# included_accounts:
# - ACCOUNT_*
# excluded_accounts:
# - ACCOUNT_SENSITIVE
properties:
name: iambic_test_permission_set
description: Permission set for testing IAMbic
inline_policy:
statement:
- action:
- "*"
effect: Deny
resource:
- "*"
managed_policies:
- arn: arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
permissions_boundary:
managed_policy_arn: arn:aws:iam::aws:policy/AWSDirectConnectReadOnlyAccess
session_duration: PT1H
4.3 - Provide Temporary Access to an AWS Identity Center Permission Set
Similarly to IAM roles, access to IAM Permission Sets can be granted temporarily. This is useful for situations where users need temporary elevated privileges (break-glass access).
access_rules:
- groups:
- GROUP_1
expires_at: tomorrow
included_accounts:
- ACCOUNT_1
4.4 Attach temporary permissions to a permission set
AWS Identity Center can be used to broker temporary AWS IAM credentials to human users. IAMbic supports
managing temporary permissions within AWS Identity Center Permission Sets.
You can include an expires_at field within the inline policy statements in your Permission Set to
specify when certain permissions should expire.
Here's an example of a Permission Set with temporary permissions that will expire in 3 days:
template_type: NOQ::AWS::IdentityCenter::PermissionSet
identifier: iambic_test_permission_set
properties:
name: iambic_test_permission_set
description: Permission set for testing IAMbic with temporary permissions
inline_policy:
expires_at: in 3 days
statement:
- action:
- "*"
effect: Deny
resource:
- "*"
managed_policies:
- arn: arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
permissions_boundary:
managed_policy_arn: arn:aws:iam::aws:policy/AWSDirectConnectReadOnlyAccess
session_duration: PT1H
After applying the changes to the Permission Set either manually, or through a GitHub PR, IAMbic will convert the relative timestamp (in 3 days) to an absolute time stamp,
and expire the permissions after the time has elapsed.
4.5 Creating a Permission Set Across Accounts with Different Permissions Through Managed Policies
In this section, we'll provide step-by-step instructions on how to create a Permission Set across accounts with different permissions through the use of a customer managed policy, which can be created separately through IAMbic.
First, use the provided managed policy template, modify ACCOUNT_A and ACCOUNT_B to match your environment, and save the template:
template_type: NOQ::AWS::IAM::ManagedPolicy
included_accounts:
- '*'
identifier: iambic_test_managed_policy
properties:
policy_document:
statement:
- included_accounts:
- '*'
action:
- sqs:*
effect: Deny
resource:
- '*'
- included_accounts:
- demo-2
action:
- s3:*
effect: Deny
resource:
- '*'
version: '2012-10-17'
policy_name: iambic_test_managed_policy
- Create a new file for the managed policy and save the provided template:
mkdir -p resources/aws/iam/managed_policy/all_accounts/
code resources/aws/iam/managed_policy/all_accounts/iambic_test_managed_policy.yaml
- Apply the changes using the IAMbic CLI:
iambic apply resources/aws/iam/managed_policy/all_accounts/iambic_test_managed_policy.yaml
- Now, create a new Identity Center Permission Set template, or modify the existing one:
mkdir -p resources/aws/identity_center/permission_set/
code resources/aws/identity_center/permission_set/iambic_test_permission_set.yaml
- In the file, specify the template type, identifier, and properties for the Permission Set. Attach the customer-managed policy created in step 1:
template_type: NOQ::AWS::IdentityCenter::PermissionSet
identifier: iambic_test_permission_set
properties:
name: iambic_test_permission_set
description: Permission set for testing IAMbic
customer_managed_policy_references:
- name: iambic_test_managed_policy
session_duration: PT1H
- Apply the changes using the IAMbic CLI:
iambic apply resources/aws/identity_center/permission_set/iambic_test_permission_set.yaml
5. Service Control Policies
Want to get a better grasp of Service Control Policies? We've got you covered! Our blog post provides real-life examples, useful tips for safe usage, and a practical guide on how to check your CloudTrail logs to ensure the SCPs you're using are safe.
This section will walk you through the process of managing, creating, and attaching Service Control Policies (SCPs) to your accounts, Organizational Units (OUs), or your entire organization. We'll also touch on how to prevent drift in your SCPs.
First, make sure IAMbic is set up with the correct AWS account and region for your AWS Organization.
If it's set up correctly, you'll see an aws.organizations section in your iambic_config.yaml file.
If you don't have a Service Control Policy in your AWS Organization yet, you might want to add
one before moving forward.
If AWS Organizations isn't set up yet, run iambic setup, select AWS, then AWS Organizations,
and follow the prompts to set up IAMbic.
Just a heads up, IAMbic only captures customer-managed SCPs. AWS-managed SCPs, like
FullAWSAccess, aren't captured by IAMbic.
5.1 - Importing Existing Service Control Policies
To import your existing SCPs, simply run the command iambic import. Your e
xisting customer-managed SCPs will then appear as IAMbic YAML templates under
resources/aws/organizations/scp/ORG_ACCOUNT_NAME, where ORG_ACCOUNT_NAME is the name of your
AWS Organization's management account.
5.2 - Creating a New Service Control Policy
This section will guide you through creating a new SCP. SCPs are like guardrails that can be applied across your organization. Since they can potentially cause outages if not applied correctly, it's crucial to test them thoroughly before implementing. For this tutorial, we'll create SCPs that only contain Allow statements to avoid accidental outages.
Replace the following placeholders in the template:
ORG_ACCOUNT_NAME: Your AWS Organization's management account name.ORG_ACCOUNT_ID: Your AWS Organization's management account ID.ORG_ID: Your AWS Organization ID.ORG_ROOT_ID: The ID of your organization's root (You can find this in the AWS Console underOrganizations > Root).
Here's a step-by-step guide:
- Create a new file for the SCP and save the template provided:
mkdir -p resources/aws/organizations/scp/ORG_ACCOUNT_NAME/
code resources/aws/organizations/scp/ORG_ACCOUNT_NAME/iambic_test_scp.yaml
- In the new file, specify the template type, identifier, and properties for the SCP.
The
iambic_managed: enforcedflag will prevent drift in a production GitOps/IAMOps setup.
This SCP should be a no-op, as it does not restrict any action
template_type: NOQ::AWS::Organizations::SCP
account_id: ORG_ACCOUNT_ID
identifier: IambicTestSCP
iambic_managed: enforced
org_id: ORG_ID
properties:
policy_document:
statement:
- action:
- '*'
effect: Allow
resource:
- '*'
version: '2012-10-17'
policy_name: IambicTestSCP
targets:
roots:
- ORG_ROOT_ID
- Apply the changes using the IAMbic CLI:
iambic apply resources/aws/organizations/scp/ORG_ACCOUNT_NAME/iambic_test_scp.yaml
In a production setup, any SCPs that are added or modified will automatically be captured in Git by IAMbic. This allows for a full audit trail of changes to your SCPs through Git History.