Skip to content

Commit b834ef0

Browse files
committed
add oidc_setup script for aws
1 parent f353d82 commit b834ef0

5 files changed

Lines changed: 1218 additions & 19 deletions

File tree

docs/scenarios/oidc-dynamic-credentials.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,82 @@ end-to-end. The blog walks through the AWS-side trust resources using the
270270
Terraform AWS provider; the policies above are the literal JSON
271271
equivalents.
272272

273+
### Reference script: bulk OIDC setup across many workspaces
274+
275+
[`examples/oidc_setup.py`](../../examples/oidc_setup.py) is a reference
276+
script for configuring OIDC federation across a list of workspaces in one
277+
invocation. Treat it as a worked example you can run as-is or adapt; it
278+
isn't part of the SDK's public API.
279+
280+
It supports two modes:
281+
282+
- **Managed-IAM** (default): the script provisions a per-workspace IAM
283+
role scoped to that workspace's OIDC `sub` claim, optionally attaches
284+
AWS-managed or inline permissions, and sets `TFC_AWS_PROVIDER_AUTH` +
285+
`TFC_AWS_RUN_ROLE_ARN` on each workspace. The IAM OIDC provider is
286+
account-global and is created once / reused across runs.
287+
288+
- **Bring-your-own-role** (`--use-existing-role <ARN>`): the script makes
289+
no AWS API calls. It just sets the OIDC env vars on each workspace
290+
pointing at a role ARN you manage elsewhere (e.g. with the Terraform
291+
AWS provider). Useful when your IAM is owned by a separate team or
292+
pipeline.
293+
294+
```bash
295+
export TFE_TOKEN=<hcp-token>
296+
297+
# Managed-IAM:
298+
export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... AWS_SESSION_TOKEN=...
299+
python examples/oidc_setup.py \
300+
--cloud aws \
301+
--org my-org \
302+
--workspaces prod-app,staging-app,dev-app \
303+
--attach-managed-policy arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
304+
305+
# Bring-your-own-role (no AWS credentials needed):
306+
python examples/oidc_setup.py \
307+
--cloud aws \
308+
--org my-org \
309+
--workspaces prod-app,staging-app,dev-app \
310+
--use-existing-role arn:aws:iam::111122223333:role/my-tfc-role
311+
```
312+
313+
The script is idempotent (safe to re-run), reports per-workspace status,
314+
and exits non-zero if any workspace failed. Other flags worth knowing:
315+
`--skip-identity-provider`, `--create-missing` (create the HCP workspace
316+
if missing instead of failing), `--remove-static-aws-creds` (clean up
317+
any old `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` /
318+
`AWS_SESSION_TOKEN` env vars on the workspace), `--inline-policy`. The
319+
`--cloud` flag only accepts `aws` today; the flag exists so other
320+
providers can be added without breaking callers.
321+
322+
### Runnable end-to-end example
323+
324+
A complete, self-contained script that does the full setup (AWS OIDC
325+
provider + IAM role + trust policy + EC2 policy + HCP workspace + env vars
326+
+ Terraform upload + plan/apply + verify + destroy) is at
327+
[`examples/oidc_aws_e2e.py`](../../examples/oidc_aws_e2e.py).
328+
329+
You only need to provide the workspace name; everything else has a sane
330+
default:
331+
332+
```bash
333+
export TFE_TOKEN=<hcp-token> # user or team token
334+
export TFE_ORG=<hcp-org>
335+
export AWS_ACCESS_KEY_ID=<sandbox>
336+
export AWS_SECRET_ACCESS_KEY=<sandbox>
337+
export AWS_SESSION_TOKEN=<sandbox> # if using STS session credentials
338+
export OIDC_WORKSPACE_NAME=my-app-prod # the only project-specific input
339+
340+
python examples/oidc_aws_e2e.py
341+
```
342+
343+
The script is idempotent — safe to re-run, every AWS and HCP resource is
344+
created only if missing, and trust + IAM policies are refreshed in place.
345+
By default it terminates the test EC2 at the end (`OIDC_DESTROY_AFTER_VERIFY`
346+
defaults to `true`) but always keeps the workspace, IAM role, and OIDC
347+
provider so you can reuse the same setup for real Terraform code.
348+
273349
### Example: same setup via a variable set across many workspaces
274350

275351
```python

0 commit comments

Comments
 (0)