Skip to main content

Deploy the Spotto AWS Role with PowerShell

The PowerShell wizard, Setup-SpottoAws.ps1, creates or updates SpottoReadOnlyRole in every account in your Spotto setup package. It applies exactly the policies Spotto generated, checks that each AWS profile signs in to the expected account before changing anything, and writes a results file that you return to Spotto.

It suits organizations with several accounts. It supports up to 100 accounts per package. Prefer Bash on Linux, macOS or in the default CloudShell session? Use the Bash wizard, which shares the setup package, results format and script ownership tags.

Get The Wizard​

Setup-SpottoAws.ps1 on GitHub (public, in the spotto-tools repository, with a README).

Read it before you run it: it's one file, and your AWS admin team should know what it changes. The commands under run the wizard download the latest version for you.

Prerequisites​

  • PowerShell 7.4 or later and AWS CLI v2. AWS CloudShell has both.
  • The setup package spotto-aws-setup.json. In the Portal, select Download Setup Package on the Deploy Access step, with Bash, PowerShell or Terraform selected. Preview customers receive it from Spotto. Enter any billing export details first (find them in AWS), so one run sets up every role. If you use Discover Exports instead, see discover a Data Export instead.
  • An IAM administrator session for each account. Your own SSO profiles or CloudShell credentials are fine. Never give Spotto administrator credentials.
  • If you use a narrower role than IAM administrator, it needs these permissions in each account:
    • sts:GetCallerIdentity
    • iam:GetRole, iam:ListAttachedRolePolicies, iam:ListRolePolicies, iam:GetRolePolicy
    • iam:CreateRole, iam:TagRole, iam:UpdateAssumeRolePolicy, iam:PutRolePolicy, iam:DeleteRolePolicy, iam:AttachRolePolicy

The wizard uses the standard role name only. For a custom role name or path, use manual setup.

Run The Wizard​

In AWS CloudShell​

  1. Open CloudShell in the account you're configuring, then enter pwsh to switch to PowerShell.

  2. Upload spotto-aws-setup.json with Actions > Upload file.

  3. Download and run the wizard:

    Invoke-WebRequest `
    -Uri "https://raw.githubusercontent.com/spottoai/spotto-tools/main/onboarding/aws/Setup-SpottoAws.ps1" `
    -OutFile "./Setup-SpottoAws.ps1"

    pwsh -NoProfile -File ./Setup-SpottoAws.ps1 `
    -SetupPackagePath ./spotto-aws-setup.json
  4. When it asks for a mode, enter 2 to configure. The default, 1, only checks and changes nothing.

  5. Review the changes it lists for the account, and approve them.

  6. Download the results file it writes, with Actions > Download file, and return it to Spotto.

CloudShell uses the current authorized AWS session. That session covers its own account; for several accounts, use an authorized AWS CLI profile for each account, locally or in CloudShell.

Locally​

git clone https://github.com/spottoai/spotto-tools.git
Set-Location ./spotto-tools
pwsh -NoProfile -File ./onboarding/aws/Setup-SpottoAws.ps1 `
-SetupPackagePath /path/to/spotto-aws-setup.json `
-Profile customer-admin

Give the full path to the setup package, because the command runs from inside the cloned folder. -Profile uses one AWS CLI profile for every account, so it suits a package with one account.

For several accounts, create a profile map that gives the AWS CLI profile for each account ID, and pass it with -ProfileMapPath:

{
"111122223333": "management-admin",
"444455556666": "billing-admin"
}

With several accounts and no map, the wizard asks for a profile for each account.

As in CloudShell, enter 2 at the mode prompt to configure, approve the changes, then return the results.

Other options:

OptionWhat it does
-OutputPathWhere to write the results file. By default it goes in the current folder, and an existing file is never overwritten.
-RegionThe Region used for AWS CLI calls. The default is us-east-1. Change it if an SCP denies that Region. GovCloud and China Regions aren't accepted.

Choose A Mode​

When run interactively, the wizard asks which mode to use, and check is the default. It asks again before changing anything.

ModeHowWhat it does
CheckThe default at the prompt, or -CheckOnlyCompares each account with the package and reports configuration-matches or changes-required. Makes no changes.
Preview-WhatIfLists the exact changes it would make, and reports accounts that need them as planned. Makes no changes.
ConfigureChoose configure when askedShows the planned changes for each account and asks for approval. After approval, rechecks the account and role, then applies only what differs.
Unattended-NonInteractive -Confirm:$falseConfigures without prompts. Use only after reviewing the package. Add -CheckOnly for an unattended check instead.

-NonInteractive defaults to a read-only check unless you explicitly pass -Confirm:$false to configure. -CheckOnly and -WhatIf still prevent writes. It needs -SetupPackagePath, and with several accounts, a profile map entry for every account.

Reruns are safe. An unchanged account isn't written to, and a rerun after a partial failure finishes only what's missing.

What The Wizard Changes​

In each account, the wizard:

  • Creates SpottoReadOnlyRole with the trust policy from the package, tagged SpottoCompanyId and SpottoManagedBy=Setup-SpottoAws.
  • Adds SpottoGuardrails, including the versioned discovery allowlist and secret-value denies. The current package has no AWS managed discovery-policy attachments.
  • Replaces an existing role's trust policy if it differs from the package. This removes any other trust statements; the plan shows how many.
  • Adds SpottoBillingExportRead and SpottoCommitmentsPlanning where the account needs them, and removes them when the package no longer includes them.

It never deletes roles, removes other policies you added, or changes permissions boundaries. It doesn't create billing exports, buckets or security services. Both scripts report a non-blocking warning if legacy ReadOnlyAccess or SecurityAudit attachments are present but not requested by the package. They do not detach them, and the warning does not prevent a configuration-matches result. Apply the generated replacement, verify effective access and collection in Spotto, then remove those attachments through the tool that owns the role. See updating an existing role.

Existing Roles​

  • A role that already matches the package is reported as configured in configure mode or configuration-matches in check-only mode, with no changes.
  • Bash and PowerShell share SpottoManagedBy=Setup-SpottoAws and SpottoCompanyId, so either script can maintain a role created by the other. Run one writer at a time for each role. Ownership tag keys are checked case-insensitively; values must match exactly.
  • To update an unmanaged role that neither script created, rerun with -RepairExistingRole and approve the listed changes.
  • The wizard refuses roles tagged for another Spotto company and roles that trust a different External ID.
  • Any SpottoManagedBy value other than the exact Setup-SpottoAws, including an empty value, makes the role verify-only, even with -RepairExistingRole. That includes roles from the Terraform module (Terraform) and Spotto's CloudFormation template (CloudFormation).
  • CloudFormation's own aws:cloudformation:* tags also make the role verify-only. An exact configuration match succeeds without writes; drift is listed and refused in configure mode. Apply changes through the owning tool or stack.
  • For roles owned by CDK, StackSets or Control Tower customizations, apply the policies there too, or the next deployment reverts them.

Return The Results​

The wizard writes SpottoAwsOnboarding-<timestamp>-<suffix>.json. It contains your Spotto company ID, the account and billing configuration from the setup package, and each account's role ARN and outcome. It contains no credentials and no External ID.

  • Preview customers: send the file to your Spotto contact.
  • Portal users: paste the full file into Setup Results JSON, select Read Setup Results, then select Create or Update.

An outcome of configured means the IAM changes were applied. It doesn't prove that Spotto can read everything; SCPs, permissions boundaries, bucket policies and KMS key policies can still deny access. Spotto checks that when it validates the connection.

If any account fails, the wizard exits with code 1 and still writes results for every account it attempted.

Troubleshooting​

SymptomCauseFix
Download Setup Package is disabledThe message under the button gives the reason: the account details aren't complete yet, a billing source is missing its export details or S3 destination, there are more than 100 enabled accounts, or an account uses a custom role ARN. It's also disabled if you can't manage AWS cloud accounts.Do what the message says. For billing, enter the export details. Use manual setup for custom role ARNs.
The wizard stops before changing anythingA profile signed in to a different account than expectedFix the profile or profile map, then rerun. No results file is written.
Existing role is not owned by this script. Review the changes above, then rerun with -RepairExistingRole to explicitly adopt it.The role wasn't created by the wizardReview it, then rerun with -RepairExistingRole.
A CloudFormation-owned role differs from the packageThe role is verify-only, including when it carries CloudFormation stack tagsUpdate the stack with the new template from Spotto. See update the role.
An account result is failedAWS denied a provisioning call, or the role is refused for one of the reasons aboveCheck the wizard output and your IAM permissions in that account, then rerun.
Use the complete results JSON from Bash, PowerShell or Terraform, without credentials or extra fields.The pasted results were edited, incomplete or not from the wizardPaste the whole results file, unchanged.
This results file exceeds the 1 MiB limit.The file is too largePaste the file the wizard wrote, not a combined or edited one.
These results belong to another company. Download a setup package for this company.The package was for a different Spotto companyUse the package for this company.
The AWS configuration has changed. Download a new setup package and run Bash, PowerShell or Terraform again.The configuration changed after the package was downloadedDownload a new package and rerun. Unchanged accounts aren't written to again.