Skip to main content
Your progress
0 of 5 complete0%
T1 / M1.1 / L2 OF 4 / Operator LEVEL / 10 min

AWS: the IAM policy and why it's read-mostly

Outcome

By the end of this lesson, you will be able to configure the AWS IAM role for ZopNight and explain which permissions enable read-only discovery versus write execution.


PrerequisitesL1
Time10 minutes

1. Concept

You do not give ZopNight a password or an access key. You create an IAM role in your AWS account, which is a named set of permissions, and you allow ZopNight to borrow it. AWS calls that assuming a role.

ZopNight runs on Google Cloud, so it borrows the role with its own Google identity. It presents a Google-signed identity token, and AWS exchanges that for short-lived role credentials (sts:AssumeRoleWithWebIdentity). ZopNight calls this method WIF-Assume Role, short for Workload Identity Federation, and it is the recommended way to connect. Nothing long-lived is stored. Static access keys and temporary STS credentials are also accepted, but the role is the method this lesson teaches.

You keep the role. You decide what is in it, and you can change or delete it at any time without involving anyone.

The read-only part

Finding resources, reading their usage, pulling the bill and producing recommendations all need permission to look and nothing more. ZopNight gives you a CloudFormation template that builds the role, and its read part is made of:

  • ReadOnlyAccess, the AWS-managed read-only policy, kept as a safety net for any read ZopNight has not listed explicitly
  • ZopNightReadPolicyA, B and C, three managed policies that list every read action ZopNight uses, service by service (EC2, RDS, EKS, Lambda, S3, CloudWatch metrics, Cost Explorer, Resource Explorer and the rest)

Open any of them in the IAM console and read the verbs. They are Describe, Get, List and similar read actions. None of them changes anything.

Deploy only this and you get the full picture: every resource found, every report, every recommendation. What you do not get is anything happening. No schedules, no automatic fixes. This is what “monitor mode” means, and it is a perfectly reasonable place to stop.

The parts that can change something

If you want schedules and fixes, you choose the read_write permission level when you launch the stack (the template’s PermissionLevel parameter is read_only or read_write). That adds two more managed policies to the role:

  • ZopNightWritePolicy: the actions schedules and scaling need, such as ec2:StartInstances, ec2:StopInstances and the Auto Scaling and Application Auto Scaling policy calls
  • ZopNightRemediationPolicy: the actions a remediation needs, such as ec2:DeleteVolume for an orphaned volume

If you start read-only, a separate upgrade template attaches the same write policies to your existing role later.

ZopNight’s write policies apply to "Resource": "*" and carry no Condition block. If you want AWS itself to refuse anything outside dev, test and stage, add your own Deny statement to the role. An extra Allow with a condition would not restrict anything, because the write policy already allows these actions on every resource. For example:

Terminal window
{
"Sid": "DenyStartStopOutsideNonProd",
"Effect": "Deny",
"Action": ["ec2:StartInstances", "ec2:StopInstances"],
"Resource": "*",
"Condition": {
"StringNotEquals": {"aws:ResourceTag/environment": ["dev", "test", "stage"]}
}
}

That is worth dwelling on. With a statement like this in place, if somebody sets up a ZopNight schedule badly and it tries to stop a production machine, AWS refuses the request. Instances with no environment tag are refused too. The protection lives in your account, not in ours. It is your addition, though: ZopNight does not ship it, so check that it matches how your resources are actually tagged.

Anything ZopNight asks for passes through AWS’s own permission check before it reaches a resource.

Saying who may borrow the role

The role also carries a short document naming who is allowed to assume it. For ZopNight it trusts Google as an identity provider, and only one Google identity, ZopNight’s own:

Terminal window
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<your-account-id>:oidc-provider/accounts.google.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"accounts.google.com:aud": "<ZopNight service account ID>",
"accounts.google.com:sub": "<ZopNight service account ID>"
}
}
}]
}

The role trusts one federated identity provider, accounts.google.com, and the condition pins it to ZopNight’s Google service account: a token from any other Google identity is refused by AWS. The CloudFormation stack also registers the accounts.google.com identity provider in your account if it is not there yet.

When you connect, ZopNight works out which AWS account it reached from what AWS itself reports back, not from anything typed into the form.

Why it is not simply read-only

A purely read-only role means no schedules, no automatic fixes, no scaling changes. That is a reporting tool, and reporting is the thing you already have.

So the honest description is read-mostly. Reading is the floor. Every ability to change something sits above it, and only you add it.

Many customers connect an account as read_only first and switch it to read_write later, once they are comfortable with what the product does. That order is deliberate: you see the findings before you allow any change.

The level is enforced by ZopNight’s servers every time an action runs, not just by hiding buttons. If someone tries to stop an instance on a read_only account, ZopNight refuses before any call reaches AWS. Discovery and recommendations still work at read_only. Actions that change your cloud are held back, and so is attaching the account’s resources to a schedule, because a schedule exists to change them. When you change the level, running schedules pick it up without a restart.

When you have many AWS accounts

Large companies run an AWS Organization with dozens or hundreds of accounts under it. ZopNight connects them one at a time:

  • Each AWS account gets its own copy of the CloudFormation stack and its own role
  • Each one is then added in ZopNight as its own cloud account, under your one ZopNight organisation
  • There is no StackSet template and no organisation-wide rollout from ZopNight; if you use your own automation to launch the stack in many accounts, you still add each account in ZopNight

2. Demo

A typical AWS connection walkthrough:

Terminal window
T+0 Customer opens ZopNight → Cloud Accounts → Add AWS Account
T+1 min ZopNight displays the IAM trust policy + permissions template
T+1 min Customer copies the CloudFormation template URL
T+2 min Customer launches in AWS CloudFormation Console
T+3 min Stack creates the IAM role
T+4 min Customer pastes the role ARN (a stack output) back to ZopNight
T+4 min ZopNight validates via STS AssumeRoleWithWebIdentity
T+5 min Account marked Active; discovery preview begins

Five minutes from start to active. The CloudFormation template eliminates manual IAM policy editing.


3. Hands-on (6 min)

Connect an AWS account (or audit one already connected):

Terminal window
1. In ZopNight, navigate to Cloud Accounts → Add AWS Account.
2. Note the offered CloudFormation template URL.
3. In AWS Console (a sandbox account, not production), launch the stack.
4. Inspect the IAM role created. Verify:
- The read policies hold only read actions
(the write policies appear only if you chose read_write)
- The trust policy names accounts.google.com and
sts:AssumeRoleWithWebIdentity
5. Paste the role ARN back to ZopNight; verify connection in <60 seconds.
6. After connection, open Permission Visibility (covered in L4) and
confirm Granted across the expected service categories.

4. Knowledge check

Q1

The AWS IAM role for ZopNight discovery is described as “read-mostly” because:

A. The baseline is read-only across all services needed for discovery, metrics, billing, and recommendations
B. It uses an old API
C. It only has around 50% of the permissions that it actually needs in order to function correctly
D. It can only read every other request

Show answer

Correct: A. Writes (StartInstances, StopInstances, DeleteVolume and so on) come only with the read_write permission level, which the customer chooses. Read-mostly = read-only baseline + writes the customer opts into.

Q2

How does ZopNight’s recommended AWS connection prove to AWS that it may assume your role?

A. It sends a long-lived IAM user access key that you created and pasted into ZopNight
B. It signs every request with a client certificate that your own AWS private CA issued to ZopNight
C. It presents a Google-signed token, and the trust policy accepts only ZopNight’s own Google identity
D. It logs in to the AWS console with an IAM user and password stored in the vault

Show answer

Correct: C. The role trusts accounts.google.com and allows sts:AssumeRoleWithWebIdentity only when the token’s audience and subject are ZopNight’s Google service account. There is no long-lived secret.

Q3

A team wants ZopNight to schedule EC2 instances tagged environment=dev but never anything tagged environment=prod. The defensible IAM configuration:

A. Add a Deny on ec2:StartInstances and ec2:StopInstances when aws:ResourceTag/environment is not in [“dev”, “test”, “stage”]
B. Don’t grant EC2 start/stop permissions
C. Rely on ZopNight never requesting anything in production, since the product does not target production resources by default
D. Use a separate AWS account for dev

Show answer

Correct: A. ZopNight’s own write policy has no tag condition and already allows these actions on every resource, so the restriction has to be a Deny that you add to the role. Once it is there, AWS refuses any request on a resource not tagged dev, test or stage (untagged ones included) before it reaches the instance. The defense is at the cloud provider’s policy layer, not the application layer, so even a buggy call cannot stop a prod instance.


5. Apply

ZopNight publishes the current policy and the CloudFormation template at:

For organizations with many AWS accounts: launch the stack once per account (with your own automation if you like), then add each account in ZopNight.


Glossary terms touched

IAM role · Assume-role · Workload identity federation


Start with the bill.

Foundations takes about five hours. The first lesson is nine minutes.

Free curriculum. No paywall. 290 lessons across 7 courses, plus an optional 24-lesson beginner course. Browse every course without an account; a free account opens the lessons, saves your progress and opens the exams for three publicly verifiable credentials. Read it on the train, take the exam on a Saturday, list the credential on your résumé Monday.

5h median time to finish Foundations
free account, every course, no paywall
3 certifications, each with a public verifier
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·