@jjrawlins/cdk-diff-pr-github-action 1.1.5 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/.jsii +94 -18
  2. package/API.md +148 -12
  3. package/README.md +115 -20
  4. package/lib/CdkDiffIamTemplate.d.ts +51 -5
  5. package/lib/CdkDiffIamTemplate.js +239 -8
  6. package/lib/CdkDiffIamTemplateStackSet.js +2 -2
  7. package/lib/CdkDiffStackWorkflow.js +1 -1
  8. package/lib/CdkDriftDetectionWorkflow.js +1 -1
  9. package/lib/CdkDriftIamTemplate.js +2 -2
  10. package/node_modules/@aws-sdk/client-cloudformation/package.json +6 -6
  11. package/node_modules/@aws-sdk/client-sso/package.json +5 -5
  12. package/node_modules/@aws-sdk/core/package.json +2 -2
  13. package/node_modules/@aws-sdk/credential-provider-env/package.json +2 -2
  14. package/node_modules/@aws-sdk/credential-provider-http/package.json +2 -2
  15. package/node_modules/@aws-sdk/credential-provider-ini/package.json +9 -9
  16. package/node_modules/@aws-sdk/credential-provider-login/package.json +3 -3
  17. package/node_modules/@aws-sdk/credential-provider-node/package.json +7 -7
  18. package/node_modules/@aws-sdk/credential-provider-process/package.json +2 -2
  19. package/node_modules/@aws-sdk/credential-provider-sso/package.json +4 -4
  20. package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +3 -3
  21. package/node_modules/@aws-sdk/middleware-user-agent/package.json +3 -3
  22. package/node_modules/@aws-sdk/nested-clients/package.json +5 -5
  23. package/node_modules/@aws-sdk/token-providers/package.json +3 -3
  24. package/node_modules/@aws-sdk/util-endpoints/package.json +1 -1
  25. package/node_modules/@aws-sdk/util-user-agent-node/package.json +2 -2
  26. package/node_modules/@aws-sdk/xml-builder/package.json +2 -2
  27. package/package.json +3 -3
  28. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/LICENSE +0 -201
  29. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/README.md +0 -6
  30. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-cjs/index.js +0 -415
  31. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-cjs/lib/aws/partitions.json +0 -267
  32. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/aws.js +0 -10
  33. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/index.js +0 -6
  34. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/lib/aws/index.js +0 -3
  35. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/lib/aws/isVirtualHostableS3Bucket.js +0 -25
  36. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/lib/aws/parseArn.js +0 -18
  37. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/lib/aws/partition.js +0 -41
  38. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/lib/aws/partitions.json +0 -267
  39. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/lib/isIpAddress.js +0 -1
  40. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/resolveDefaultAwsRegionalEndpointsConfig.js +0 -21
  41. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/resolveEndpoint.js +0 -1
  42. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/types/EndpointError.js +0 -1
  43. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/types/EndpointRuleObject.js +0 -1
  44. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/types/ErrorRuleObject.js +0 -1
  45. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/types/RuleSetObject.js +0 -1
  46. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/types/TreeRuleObject.js +0 -1
  47. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/types/index.js +0 -6
  48. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-es/types/shared.js +0 -1
  49. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/aws.d.ts +0 -2
  50. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/index.d.ts +0 -6
  51. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/lib/aws/index.d.ts +0 -3
  52. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/lib/aws/isVirtualHostableS3Bucket.d.ts +0 -5
  53. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/lib/aws/parseArn.d.ts +0 -7
  54. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/lib/aws/partition.d.ts +0 -38
  55. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/lib/isIpAddress.d.ts +0 -1
  56. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/resolveDefaultAwsRegionalEndpointsConfig.d.ts +0 -56
  57. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/resolveEndpoint.d.ts +0 -1
  58. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/aws.d.ts +0 -2
  59. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/index.d.ts +0 -6
  60. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/lib/aws/index.d.ts +0 -3
  61. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/lib/aws/isVirtualHostableS3Bucket.d.ts +0 -4
  62. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/lib/aws/parseArn.d.ts +0 -2
  63. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/lib/aws/partition.d.ts +0 -28
  64. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/lib/isIpAddress.d.ts +0 -1
  65. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/resolveDefaultAwsRegionalEndpointsConfig.d.ts +0 -35
  66. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/resolveEndpoint.d.ts +0 -1
  67. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/types/EndpointError.d.ts +0 -1
  68. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/types/EndpointRuleObject.d.ts +0 -6
  69. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/types/ErrorRuleObject.d.ts +0 -1
  70. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/types/RuleSetObject.d.ts +0 -5
  71. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/types/TreeRuleObject.d.ts +0 -1
  72. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/types/index.d.ts +0 -6
  73. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/ts3.4/types/shared.d.ts +0 -12
  74. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/types/EndpointError.d.ts +0 -1
  75. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/types/EndpointRuleObject.d.ts +0 -1
  76. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/types/ErrorRuleObject.d.ts +0 -1
  77. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/types/RuleSetObject.d.ts +0 -1
  78. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/types/TreeRuleObject.d.ts +0 -1
  79. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/types/index.d.ts +0 -6
  80. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/dist-types/types/shared.d.ts +0 -1
  81. package/node_modules/@aws-sdk/client-cloudformation/node_modules/@aws-sdk/util-endpoints/package.json +0 -60
package/.jsii CHANGED
@@ -7,7 +7,7 @@
7
7
  ]
8
8
  },
9
9
  "bundled": {
10
- "@aws-sdk/client-cloudformation": "^3.981.0",
10
+ "@aws-sdk/client-cloudformation": "^3.982.0",
11
11
  "@types/crypto-js": "^4.2.2",
12
12
  "@types/js-yaml": "^4.0.9",
13
13
  "crypto-js": "^4.2.0",
@@ -3549,7 +3549,7 @@
3549
3549
  },
3550
3550
  "name": "@jjrawlins/cdk-diff-pr-github-action",
3551
3551
  "readme": {
3552
- "markdown": "# cdk-diff-pr-github-action\n\nA library that provides GitHub workflows and IAM templates for:\n- Creating CloudFormation Change Sets for your CDK stacks on pull requests and commenting a formatted diff back on the PR.\n- Detecting CloudFormation drift on a schedule or manual trigger and producing a consolidated summary (optionally creating an issue).\n- Deploying IAM roles across AWS Organizations using StackSets.\n\nIt also provides ready‑to‑deploy IAM templates with the minimal permissions required for each workflow.\n\n**Works with or without Projen** — The StackSet generator can be used standalone in any Node.js project.\n\nThis package exposes five constructs:\n\n- `CdkDiffStackWorkflow` — Generates one GitHub Actions workflow per stack to create a change set and render the diff back to the PR and Step Summary.\n- `CdkDiffIamTemplate` — Emits a CloudFormation template file with minimal permissions for the Change Set workflow.\n- `CdkDriftDetectionWorkflow` — Generates a GitHub Actions workflow to detect CloudFormation drift per stack, upload machine‑readable results, and aggregate a summary.\n- `CdkDriftIamTemplate` — Emits a CloudFormation template file with minimal permissions for the Drift Detection workflow.\n- `CdkDiffIamTemplateStackSet` — Creates a CloudFormation StackSet template for org-wide deployment of GitHub OIDC and IAM roles (Projen integration).\n- `CdkDiffIamTemplateStackSetGenerator` — Pure generator class for StackSet templates (no Projen dependency).\n\n## Quick start\n\n1) Add the constructs to your Projen project (in `.projenrc.ts`).\n2) Synthesize with `npx projen`.\n3) Commit the generated files.\n4) Open a pull request or run the drift detection workflow.\n\n## Usage: CdkDiffStackWorkflow\n\n`CdkDiffStackWorkflow` renders a workflow per stack named `diff-<StackName>.yml` under `.github/workflows/`. It also generates a helper script at `.github/workflows/scripts/describe-cfn-changeset.ts` that formats the change set output and takes care of posting the PR comment and Step Summary.\n\nExample `.projenrc.ts`:\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDiffStackWorkflow } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({\n // ... your usual settings ...\n workflowName: 'my-lib',\n defaultReleaseBranch: 'main',\n cdkVersion: '2.85.0',\n github: true,\n});\n\nnew CdkDiffStackWorkflow({\n project,\n stacks: [\n {\n stackName: 'MyAppStack',\n changesetRoleToAssumeArn: 'arn:aws:iam::123456789012:role/cdk-diff-role',\n changesetRoleToAssumeRegion: 'us-east-1',\n // Optional per‑stack OIDC override (if not using the defaults below)\n // oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n // oidcRegion: 'us-east-1',\n },\n ],\n // Default OIDC role/region used by all stacks unless overridden per‑stack\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n // Optional: Node version used in the workflow (default: '24.x')\n // nodeVersion: '24.x',\n // Optional: Yarn command to run CDK (default: 'cdk')\n // cdkYarnCommand: 'cdk',\n // Optional: Where to place the helper script (default: '.github/workflows/scripts/describe-cfn-changeset.ts')\n // scriptOutputPath: '.github/workflows/scripts/describe-cfn-changeset.ts',\n});\n\nproject.synth();\n```\n\n### CdkDiffStackWorkflow props\n- `project` (required) — Your Projen project instance.\n- `stacks` (required) — Array of stack entries.\n- `oidcRoleArn` (required unless provided per‑stack) — Default OIDC role ARN.\n- `oidcRegion` (required unless provided per‑stack) — Default OIDC region.\n- `nodeVersion` (optional, default `'24.x'`) — Node.js version for the workflow runner.\n- `cdkYarnCommand` (optional, default `'cdk'`) — Yarn script/command to invoke CDK.\n- `scriptOutputPath` (optional, default `'.github/workflows/scripts/describe-cfn-changeset.ts'`) — Where to write the helper script.\n\nIf neither top‑level OIDC defaults nor all per‑stack values are supplied, the construct throws a helpful error.\n\n### Stack item fields\n- `stackName` (required) — The CDK stack name to create the change set for.\n- `changesetRoleToAssumeArn` (required) — The ARN of the role used to create the change set (role chaining after OIDC).\n- `changesetRoleToAssumeRegion` (required) — The region for that role.\n- `oidcRoleArn` (optional) — Per‑stack override for the OIDC role.\n- `oidcRegion` (optional) — Per‑stack override for the OIDC region.\n\n### What gets generated\n- `.github/workflows/diff-<StackName>.yml` — One workflow per stack, triggered on PR open/sync/reopen.\n- `.github/workflows/scripts/describe-cfn-changeset.ts` — A helper script that:\n - Polls `DescribeChangeSet` until terminal\n - Filters out ignorable logical IDs or resource types using environment variables `IGNORE_LOGICAL_IDS` and `IGNORE_RESOURCE_TYPES`\n - Renders an HTML table with actions, logical IDs, types, replacements, and changed properties\n - Prints the HTML, appends to the GitHub Step Summary, and (if `GITHUB_TOKEN` and `GITHUB_COMMENT_URL` are present) posts a PR comment\n\n### Environment variables used by the change set script\n- `STACK_NAME` (required) — Stack name to describe.\n- `CHANGE_SET_NAME` (default: same as `STACK_NAME`).\n- `AWS_REGION` — Region for CloudFormation API calls. The workflow sets this via the credentials action(s).\n- `GITHUB_TOKEN` (optional) — If set with `GITHUB_COMMENT_URL`, posts a PR comment.\n- `GITHUB_COMMENT_URL` (optional) — PR comments URL.\n- `GITHUB_STEP_SUMMARY` (optional) — When present, appends the HTML to the step summary file.\n- `IGNORE_LOGICAL_IDS` (optional) — Comma‑separated logical IDs to ignore (default includes `CDKMetadata`).\n- `IGNORE_RESOURCE_TYPES` (optional) — Comma‑separated resource types to ignore (e.g., `AWS::CDK::Metadata`).\n\n## Usage: CdkDiffIamTemplate\n\nEmit an example IAM template you can deploy in your account for the Change Set workflow.\n\n### With Projen\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDiffIamTemplate } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({\n // ...\n});\n\nnew CdkDiffIamTemplate({\n project,\n roleName: 'cdk-diff-role',\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n // Optional: custom output path (default: 'cdk-diff-workflow-iam-template.yaml')\n // outputPath: 'infra/cdk-diff-iam.yaml',\n});\n\nproject.synth();\n```\n\nA Projen task is also added:\n\n```bash\nnpx projen deploy-cdkdiff-iam-template -- --parameter-overrides GitHubOIDCRoleArn=... # plus any extra AWS CLI args\n```\n\n### Without Projen (Standalone Generator)\n\n```ts\nimport { CdkDiffIamTemplateGenerator } from '@jjrawlins/cdk-diff-pr-github-action';\nimport * as fs from 'fs';\n\nconst template = CdkDiffIamTemplateGenerator.generateTemplate({\n roleName: 'cdk-diff-role',\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n});\n\nfs.writeFileSync('cdk-diff-iam-template.yaml', template);\n\n// Get the deploy command\nconst deployCmd = CdkDiffIamTemplateGenerator.generateDeployCommand('cdk-diff-iam-template.yaml');\nconsole.log('Deploy with:', deployCmd);\n```\n\n### What the template defines\n\n- Parameter `GitHubOIDCRoleArn` with a default from `oidcRoleArn` — the ARN of your existing GitHub OIDC role allowed to assume the change set role.\n- IAM role `CdkChangesetRole` with minimal permissions for:\n - CloudFormation Change Set operations\n - Access to common CDK bootstrap S3 buckets and SSM parameters\n - `iam:PassRole` to `cloudformation.amazonaws.com`\n- Outputs exporting the role name and ARN.\n\nUse the created role ARN as `changesetRoleToAssumeArn` in `CdkDiffStackWorkflow`.\n\n---\n\n## Usage: CdkDriftDetectionWorkflow\n\n`CdkDriftDetectionWorkflow` creates a single workflow file (default `drift-detection.yml`) that can run on a schedule and via manual dispatch. It generates a helper script at `.github/workflows/scripts/detect-drift.ts` (by default) that uses AWS SDK v3 to run drift detection, write optional machine‑readable JSON, and print an HTML report for the Step Summary.\n\nExample `.projenrc.ts`:\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDriftDetectionWorkflow } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({ github: true, /* ... */ });\n\nnew CdkDriftDetectionWorkflow({\n project,\n workflowName: 'Drift Detection', // optional; file name derived as 'drift-detection.yml'\n schedule: '0 1 * * *', // optional cron\n createIssues: true, // default true; create/update issue when drift detected on schedule\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n // Optional: Node version (default '24.x')\n // nodeVersion: '24.x',\n // Optional: Where to place the helper script (default '.github/workflows/scripts/detect-drift.ts')\n // scriptOutputPath: '.github/workflows/scripts/detect-drift.ts',\n stacks: [\n {\n stackName: 'MyAppStack-Prod',\n driftDetectionRoleToAssumeArn: 'arn:aws:iam::123456789012:role/cdk-drift-role',\n driftDetectionRoleToAssumeRegion: 'us-east-1',\n // failOnDrift: true, // optional (default true)\n },\n ],\n});\n\nproject.synth();\n```\n\n### CdkDriftDetectionWorkflow props\n- `project` (required) — Your Projen project instance.\n- `stacks` (required) — Array of stacks to check.\n- `oidcRoleArn` (required) — Default OIDC role ARN used before chaining into per‑stack drift roles.\n- `oidcRegion` (required) — Default OIDC region.\n- `workflowName` (optional, default `'drift-detection'`) — Human‑friendly workflow name; the file name is derived in kebab‑case.\n- `schedule` (optional) — Cron expression for automatic runs.\n- `createIssues` (optional, default `true`) — When true, scheduled runs will create/update a GitHub issue if drift is detected.\n- `nodeVersion` (optional, default `'24.x'`) — Node.js version for the runner.\n- `scriptOutputPath` (optional, default `'.github/workflows/scripts/detect-drift.ts'`) — Where to write the helper script.\n\n### Per‑stack fields\n- `stackName` (required) — The full CloudFormation stack name.\n- `driftDetectionRoleToAssumeArn` (required) — Role to assume (after OIDC) for making drift API calls.\n- `driftDetectionRoleToAssumeRegion` (required) — Region for that role and API calls.\n- `failOnDrift` (optional, default `true`) — Intended to fail the detection step on drift. The provided script exits with non‑zero when drift is found; the job continues to allow artifact upload and issue creation.\n\n### What gets generated\n- `.github/workflows/<kebab(workflowName)>.yml` — A workflow with one job per stack plus a final summary job.\n- `.github/workflows/scripts/detect-drift.ts` — Helper script that:\n - Starts drift detection and polls until completion\n - Lists non‑`IN_SYNC` resources and builds an HTML report\n - Writes optional JSON to `DRIFT_DETECTION_OUTPUT` when set\n - Prints to stdout and appends to the GitHub Step Summary when available\n\n### Artifacts and summary\n- Each stack job uploads `drift-results-<stack>.json` (if produced).\n- A final `Drift Detection Summary` job downloads all artifacts and prints a consolidated summary.\n\n### Manual dispatch\n- The workflow exposes an input named `stack` with choices including each configured stack and an `all` option.\n- Choose a specific stack to run drift detection for that stack only, or select `all` (or leave the input empty) to run all stacks.\n\nNote: The default workflow does not post PR comments for drift. It can create/update an Issue on scheduled runs when `createIssues` is `true`.\n\n### Post-notification steps (e.g., Slack)\n\nYou can add your own GitHub Action steps to run after the drift detection step for each stack using `postGitHubSteps`.\nProvide your own Slack payload/markdown (this library no longer generates a payload step for you).\n\nOption A: slackapi/slack-github-action (Incoming Webhook, official syntax)\n\n```ts\nnew CdkDriftDetectionWorkflow({\n project,\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n stacks: [/* ... */],\n postGitHubSteps: ({ stack }) => {\n // Build a descriptive name per stack\n const name = `Notify Slack (${stack} post-drift)`;\n const step = {\n name,\n uses: 'slackapi/slack-github-action@v2.1.1',\n // by default, post steps run only when drift is detected; you can override `if`\n if: \"always() && steps.drift.outcome == 'failure'\",\n // Use official inputs: webhook + webhook-type, and a YAML payload with blocks\n with: {\n webhook: '${{ secrets.CDK_NOTIFICATIONS_SLACK_WEBHOOK }}',\n 'webhook-type': 'incoming-webhook',\n payload: [\n 'text: \"** ${{ env.STACK_NAME }} ** has drifted!\"',\n 'blocks:',\n ' - type: \"section\"',\n ' text:',\n ' type: \"mrkdwn\"',\n ' text: \"*Stack:* ${{ env.STACK_NAME }} (region ${{ env.AWS_REGION }}) has drifted:exclamation:\"',\n ' - type: \"section\"',\n ' fields:',\n ' - type: \"mrkdwn\"',\n ' text: \"*Stack ARN*\\\\n${{ steps.drift.outputs.stack-arn }}\"',\n ' - type: \"mrkdwn\"',\n ' text: \"*Issue*\\\\n<${{ github.server_url }}/${{ github.repository }}/issues/${{ steps.issue.outputs.result }}|#${{ steps.issue.outputs.result }}>\"',\n ].join('\\n'),\n },\n };\n return [step];\n },\n});\n```\n\nNote: The Issue link requires `createIssues: true` (default) so that the `Create Issue on Drift` step runs before this Slack step and exposes `steps.issue.outputs.result`. This library orders the steps accordingly.\n\nDetails:\n- `postGitHubSteps` can be:\n - an array of step objects, or\n - a factory function `({ stack }) => step | step[]`.\n- Each step you provide is inserted after the results are uploaded.\n- Default condition: if you do not set `if` on your step, it will default to `always() && steps.drift.outcome == 'failure'`.\n- Available context/env you can use:\n - `${{ env.STACK_NAME }}`, `${{ env.DRIFT_DETECTION_OUTPUT }}`\n - `${{ steps.drift.outcome }}` — success/failure of the detect step\n - `${{ steps.drift.outputs.stack-arn }}` — Stack ARN resolved at runtime\n - `${{ steps.issue.outputs.result }}` — Issue number if the workflow created/found one (empty when not applicable)\n```\n\n## Usage: CdkDriftIamTemplate\n\nEmit an example IAM template you can deploy in your account for the Drift Detection workflow.\n\n### With Projen\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDriftIamTemplate } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({\n // ...\n});\n\nnew CdkDriftIamTemplate({\n project,\n roleName: 'cdk-drift-role',\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n // Optional: custom output path (default: 'cdk-drift-workflow-iam-template.yaml')\n // outputPath: 'infra/cdk-drift-iam.yaml',\n});\n\nproject.synth();\n```\n\nA Projen task is also added:\n\n```bash\nnpx projen deploy-cdkdrift-iam-template -- --parameter-overrides GitHubOIDCRoleArn=... # plus any extra AWS CLI args\n```\n\n### Without Projen (Standalone Generator)\n\n```ts\nimport { CdkDriftIamTemplateGenerator } from '@jjrawlins/cdk-diff-pr-github-action';\nimport * as fs from 'fs';\n\nconst template = CdkDriftIamTemplateGenerator.generateTemplate({\n roleName: 'cdk-drift-role',\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n});\n\nfs.writeFileSync('cdk-drift-iam-template.yaml', template);\n\n// Get the deploy command\nconst deployCmd = CdkDriftIamTemplateGenerator.generateDeployCommand('cdk-drift-iam-template.yaml');\nconsole.log('Deploy with:', deployCmd);\n```\n\n### What the template defines\n\n- Parameter `GitHubOIDCRoleArn` with a default from `oidcRoleArn` — the ARN of your existing GitHub OIDC role allowed to assume this drift role.\n- IAM role `CdkDriftRole` with minimal permissions for CloudFormation drift detection operations.\n- Outputs exporting the role name and ARN.\n\n---\n\n## Usage: CdkDiffIamTemplateStackSet (Org-Wide Deployment)\n\n`CdkDiffIamTemplateStackSet` creates a CloudFormation StackSet template for deploying GitHub OIDC provider, OIDC role, and CDK diff/drift IAM roles across an entire AWS Organization. This is the recommended approach for organizations that want to enable CDK diff/drift workflows across multiple accounts.\n\n### Architecture\n\nEach account in your organization gets:\n- **GitHub OIDC Provider** — Authenticates GitHub Actions workflows\n- **GitHubOIDCRole** — Trusts the OIDC provider with repo/branch restrictions\n- **CdkChangesetRole** — For PR change set previews (trusts GitHubOIDCRole)\n- **CdkDriftRole** — For drift detection (trusts GitHubOIDCRole)\n\nThis is a self-contained deployment with **no role chaining required**.\n\n### With Projen\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDiffIamTemplateStackSet } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({ /* ... */ });\n\nnew CdkDiffIamTemplateStackSet({\n project,\n githubOidc: {\n owner: 'my-org', // GitHub org or username\n repositories: ['infra-repo', 'app-repo'], // Repos allowed to assume roles\n branches: ['main', 'release/*'], // Branch patterns (default: ['*'])\n },\n targetOrganizationalUnitIds: ['ou-xxxx-xxxxxxxx'], // Target OUs\n regions: ['us-east-1', 'eu-west-1'], // Target regions\n // Optional settings:\n // oidcRoleName: 'GitHubOIDCRole', // default\n // changesetRoleName: 'CdkChangesetRole', // default\n // driftRoleName: 'CdkDriftRole', // default\n // roleSelection: StackSetRoleSelection.BOTH, // BOTH, CHANGESET_ONLY, or DRIFT_ONLY\n // delegatedAdmin: true, // Use --call-as DELEGATED_ADMIN (default: true)\n});\n\nproject.synth();\n```\n\nThis creates:\n- `cdk-diff-workflow-stackset-template.yaml` — CloudFormation template\n- Projen tasks for StackSet management\n\n**Projen tasks:**\n```bash\nnpx projen stackset-create # Create the StackSet\nnpx projen stackset-update # Update the StackSet template\nnpx projen stackset-deploy-instances # Deploy to target OUs/regions\nnpx projen stackset-delete-instances # Remove stack instances\nnpx projen stackset-delete # Delete the StackSet\nnpx projen stackset-describe # Show StackSet status\nnpx projen stackset-list-instances # List all instances\n```\n\n### Without Projen (Standalone Generator)\n\nFor non-Projen projects, use `CdkDiffIamTemplateStackSetGenerator` directly:\n\n```ts\nimport {\n CdkDiffIamTemplateStackSetGenerator\n} from '@jjrawlins/cdk-diff-pr-github-action';\nimport * as fs from 'fs';\n\n// Generate the CloudFormation template\nconst template = CdkDiffIamTemplateStackSetGenerator.generateTemplate({\n githubOidc: {\n owner: 'my-org',\n repositories: ['infra-repo'],\n branches: ['main'],\n },\n});\n\n// Write to file\nfs.writeFileSync('stackset-template.yaml', template);\n\n// Get AWS CLI commands for StackSet operations\nconst commands = CdkDiffIamTemplateStackSetGenerator.generateCommands({\n stackSetName: 'cdk-diff-workflow-iam-stackset',\n templatePath: 'stackset-template.yaml',\n targetOrganizationalUnitIds: ['ou-xxxx-xxxxxxxx'],\n regions: ['us-east-1'],\n});\n\nconsole.log('Create StackSet:', commands['stackset-create']);\nconsole.log('Deploy instances:', commands['stackset-deploy-instances']);\n```\n\n### GitHub Actions Workflow (Simplified)\n\nWith per-account OIDC, your workflow is simplified — no role chaining needed:\n\n```yaml\njobs:\n diff:\n runs-on: ubuntu-latest\n permissions:\n id-token: write\n contents: read\n steps:\n - uses: actions/checkout@v4\n\n - uses: aws-actions/configure-aws-credentials@v4\n with:\n role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/GitHubOIDCRole\n aws-region: us-east-1\n\n - name: Assume Changeset Role\n run: |\n CREDS=$(aws sts assume-role \\\n --role-arn arn:aws:iam::${{ env.ACCOUNT_ID }}:role/CdkChangesetRole \\\n --role-session-name changeset-session)\n # Export credentials...\n```\n\n### GitHubOidcConfig options\n\n| Property | Description |\n|----------|-------------|\n| `owner` | GitHub organization or username (required) |\n| `repositories` | Array of repo names, or `['*']` for all repos (required) |\n| `branches` | Array of branch patterns (default: `['*']`) |\n| `additionalClaims` | Extra OIDC claims like `['pull_request', 'environment:production']` |\n\n---\n\n## Testing\n\nThis repository includes Jest tests that snapshot the synthesized outputs from Projen and assert that:\n- Diff workflows are created per stack and contain all expected steps.\n- Drift detection workflow produces one job per stack and a summary job.\n- Only one helper script file is generated per workflow type.\n- Per‑stack OIDC overrides (where supported) are respected.\n- Helpful validation errors are thrown for missing OIDC settings.\n- The IAM template files contain the expected resources and outputs.\n\nRun tests with:\n\n```bash\nyarn test\n```\n\n## Notes\n- This package assumes your repository is configured with GitHub Actions and that you have a GitHub OIDC role configured in AWS.\n- The generated scripts use the AWS SDK v3 for CloudFormation and, where applicable, the GitHub REST API.\n"
3552
+ "markdown": "# cdk-diff-pr-github-action\n\nA library that provides GitHub workflows and IAM templates for:\n- Creating CloudFormation Change Sets for your CDK stacks on pull requests and commenting a formatted diff back on the PR.\n- Detecting CloudFormation drift on a schedule or manual trigger and producing a consolidated summary (optionally creating an issue).\n- Deploying IAM roles across AWS Organizations using StackSets.\n\nIt also provides ready‑to‑deploy IAM templates with the minimal permissions required for each workflow.\n\n**Works with or without Projen** — The StackSet generator can be used standalone in any Node.js project.\n\nThis package exposes five constructs:\n\n- `CdkDiffStackWorkflow` — Generates one GitHub Actions workflow per stack to create a change set and render the diff back to the PR and Step Summary.\n- `CdkDiffIamTemplate` — Emits a CloudFormation template file with minimal permissions for the Change Set workflow.\n- `CdkDriftDetectionWorkflow` — Generates a GitHub Actions workflow to detect CloudFormation drift per stack, upload machine‑readable results, and aggregate a summary.\n- `CdkDriftIamTemplate` — Emits a CloudFormation template file with minimal permissions for the Drift Detection workflow.\n- `CdkDiffIamTemplateStackSet` — Creates a CloudFormation StackSet template for org-wide deployment of GitHub OIDC and IAM roles (Projen integration).\n- `CdkDiffIamTemplateStackSetGenerator` — Pure generator class for StackSet templates (no Projen dependency).\n\n## Quick start\n\n1) Add the constructs to your Projen project (in `.projenrc.ts`).\n2) Synthesize with `npx projen`.\n3) Commit the generated files.\n4) Open a pull request or run the drift detection workflow.\n\n## Usage: CdkDiffStackWorkflow\n\n`CdkDiffStackWorkflow` renders a workflow per stack named `diff-<StackName>.yml` under `.github/workflows/`. It also generates a helper script at `.github/workflows/scripts/describe-cfn-changeset.ts` that formats the change set output and takes care of posting the PR comment and Step Summary.\n\nExample `.projenrc.ts`:\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDiffStackWorkflow } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({\n // ... your usual settings ...\n workflowName: 'my-lib',\n defaultReleaseBranch: 'main',\n cdkVersion: '2.85.0',\n github: true,\n});\n\nnew CdkDiffStackWorkflow({\n project,\n stacks: [\n {\n stackName: 'MyAppStack',\n changesetRoleToAssumeArn: 'arn:aws:iam::123456789012:role/cdk-diff-role',\n changesetRoleToAssumeRegion: 'us-east-1',\n // Optional per‑stack OIDC override (if not using the defaults below)\n // oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n // oidcRegion: 'us-east-1',\n },\n ],\n // Default OIDC role/region used by all stacks unless overridden per‑stack\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n // Optional: Node version used in the workflow (default: '24.x')\n // nodeVersion: '24.x',\n // Optional: Yarn command to run CDK (default: 'cdk')\n // cdkYarnCommand: 'cdk',\n // Optional: Where to place the helper script (default: '.github/workflows/scripts/describe-cfn-changeset.ts')\n // scriptOutputPath: '.github/workflows/scripts/describe-cfn-changeset.ts',\n});\n\nproject.synth();\n```\n\n### CdkDiffStackWorkflow props\n- `project` (required) — Your Projen project instance.\n- `stacks` (required) — Array of stack entries.\n- `oidcRoleArn` (required unless provided per‑stack) — Default OIDC role ARN.\n- `oidcRegion` (required unless provided per‑stack) — Default OIDC region.\n- `nodeVersion` (optional, default `'24.x'`) — Node.js version for the workflow runner.\n- `cdkYarnCommand` (optional, default `'cdk'`) — Yarn script/command to invoke CDK.\n- `scriptOutputPath` (optional, default `'.github/workflows/scripts/describe-cfn-changeset.ts'`) — Where to write the helper script.\n\nIf neither top‑level OIDC defaults nor all per‑stack values are supplied, the construct throws a helpful error.\n\n### Stack item fields\n- `stackName` (required) — The CDK stack name to create the change set for.\n- `changesetRoleToAssumeArn` (required) — The ARN of the role used to create the change set (role chaining after OIDC).\n- `changesetRoleToAssumeRegion` (required) — The region for that role.\n- `oidcRoleArn` (optional) — Per‑stack override for the OIDC role.\n- `oidcRegion` (optional) — Per‑stack override for the OIDC region.\n\n### What gets generated\n- `.github/workflows/diff-<StackName>.yml` — One workflow per stack, triggered on PR open/sync/reopen.\n- `.github/workflows/scripts/describe-cfn-changeset.ts` — A helper script that:\n - Polls `DescribeChangeSet` until terminal\n - Filters out ignorable logical IDs or resource types using environment variables `IGNORE_LOGICAL_IDS` and `IGNORE_RESOURCE_TYPES`\n - Renders an HTML table with actions, logical IDs, types, replacements, and changed properties\n - Prints the HTML, appends to the GitHub Step Summary, and (if `GITHUB_TOKEN` and `GITHUB_COMMENT_URL` are present) posts a PR comment\n\n### Environment variables used by the change set script\n- `STACK_NAME` (required) — Stack name to describe.\n- `CHANGE_SET_NAME` (default: same as `STACK_NAME`).\n- `AWS_REGION` — Region for CloudFormation API calls. The workflow sets this via the credentials action(s).\n- `GITHUB_TOKEN` (optional) — If set with `GITHUB_COMMENT_URL`, posts a PR comment.\n- `GITHUB_COMMENT_URL` (optional) — PR comments URL.\n- `GITHUB_STEP_SUMMARY` (optional) — When present, appends the HTML to the step summary file.\n- `IGNORE_LOGICAL_IDS` (optional) — Comma‑separated logical IDs to ignore (default includes `CDKMetadata`).\n- `IGNORE_RESOURCE_TYPES` (optional) — Comma‑separated resource types to ignore (e.g., `AWS::CDK::Metadata`).\n\n## Usage: CdkDiffIamTemplate\n\nEmit an IAM template you can deploy in your account for the Change Set workflow. Supports two modes:\n\n1. **External OIDC Role** — Reference an existing GitHub OIDC role (original behavior)\n2. **Self-Contained** — Create the GitHub OIDC provider and role within the same template (new)\n\n### Option 1: Using an Existing OIDC Role (External)\n\nUse this when you already have a GitHub OIDC provider and role set up in your account.\n\n#### With Projen\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDiffIamTemplate } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({\n // ...\n});\n\nnew CdkDiffIamTemplate({\n project,\n roleName: 'cdk-diff-role',\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n // Optional: custom output path (default: 'cdk-diff-workflow-iam-template.yaml')\n // outputPath: 'infra/cdk-diff-iam.yaml',\n});\n\nproject.synth();\n```\n\n#### Without Projen (Standalone Generator)\n\n```ts\nimport { CdkDiffIamTemplateGenerator } from '@jjrawlins/cdk-diff-pr-github-action';\nimport * as fs from 'fs';\n\nconst template = CdkDiffIamTemplateGenerator.generateTemplate({\n roleName: 'cdk-diff-role',\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n});\n\nfs.writeFileSync('cdk-diff-iam-template.yaml', template);\n```\n\n### Option 2: Self-Contained Template (Create OIDC Role)\n\nUse this when you want a single template that creates everything needed — the GitHub OIDC provider, OIDC role, and changeset role. This simplifies deployment and pairs well with the `CdkDiffStackWorkflow`.\n\n#### With Projen\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDiffIamTemplate } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({\n // ...\n});\n\nnew CdkDiffIamTemplate({\n project,\n roleName: 'CdkChangesetRole',\n createOidcRole: true,\n oidcRoleName: 'GitHubOIDCRole', // Optional, default: 'GitHubOIDCRole'\n githubOidc: {\n owner: 'my-org', // GitHub org or username\n repositories: ['infra-repo', 'app-repo'], // Repos allowed to assume roles\n branches: ['main', 'release/*'], // Branch patterns (default: ['*'])\n },\n // Optional: Skip OIDC provider creation if it already exists\n // skipOidcProviderCreation: true,\n});\n\nproject.synth();\n```\n\n#### Without Projen (Standalone Generator)\n\n```ts\nimport { CdkDiffIamTemplateGenerator } from '@jjrawlins/cdk-diff-pr-github-action';\nimport * as fs from 'fs';\n\nconst template = CdkDiffIamTemplateGenerator.generateTemplate({\n roleName: 'CdkChangesetRole',\n createOidcRole: true,\n oidcRoleName: 'GitHubOIDCRole',\n githubOidc: {\n owner: 'my-org',\n repositories: ['infra-repo'],\n branches: ['main'],\n },\n});\n\nfs.writeFileSync('cdk-diff-iam-template.yaml', template);\n```\n\n#### With Existing OIDC Provider (Skip Creation)\n\nIf your account already has a GitHub OIDC provider but you want the template to create the roles:\n\n```ts\nnew CdkDiffIamTemplate({\n project,\n roleName: 'CdkChangesetRole',\n createOidcRole: true,\n skipOidcProviderCreation: true, // Account already has OIDC provider\n githubOidc: {\n owner: 'my-org',\n repositories: ['*'], // All repos in org\n },\n});\n```\n\n### Deploy Task\n\nA Projen task is added for easy deployment:\n\n```bash\nnpx projen deploy-cdkdiff-iam-template -- --parameter-overrides GitHubOIDCRoleArn=... # plus any extra AWS CLI args\n```\n\n### CdkDiffIamTemplate Props\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `roleName` | `string` | Name for the changeset IAM role (required) |\n| `oidcRoleArn` | `string?` | ARN of existing GitHub OIDC role. Required when `createOidcRole` is false. |\n| `oidcRegion` | `string?` | Region for OIDC trust condition. Required when `createOidcRole` is false. |\n| `createOidcRole` | `boolean?` | Create OIDC role within template (default: false) |\n| `oidcRoleName` | `string?` | Name of OIDC role to create (default: 'GitHubOIDCRole') |\n| `githubOidc` | `GitHubOidcConfig?` | GitHub OIDC config. Required when `createOidcRole` is true. |\n| `skipOidcProviderCreation` | `boolean?` | Skip OIDC provider if it exists (default: false) |\n| `outputPath` | `string?` | Template output path (default: 'cdk-diff-workflow-iam-template.yaml') |\n\n### What the Template Creates\n\n**External OIDC Role mode:**\n- Parameter `GitHubOIDCRoleArn` — ARN of your existing GitHub OIDC role\n- IAM role `CdkChangesetRole` with minimal permissions for change set operations\n- Outputs: `CdkChangesetRoleArn`, `CdkChangesetRoleName`\n\n**Self-Contained mode (`createOidcRole: true`):**\n- GitHub OIDC Provider (unless `skipOidcProviderCreation: true`)\n- IAM role `GitHubOIDCRole` with trust policy for GitHub Actions\n- IAM role `CdkChangesetRole` with minimal permissions (trusts the OIDC role)\n- Outputs: `GitHubOIDCProviderArn`, `GitHubOIDCRoleArn`, `GitHubOIDCRoleName`, `CdkChangesetRoleArn`, `CdkChangesetRoleName`\n\n**Changeset Role Permissions:**\n- CloudFormation Change Set operations\n- Access to CDK bootstrap S3 buckets and SSM parameters\n- `iam:PassRole` to `cloudformation.amazonaws.com`\n\nUse the created changeset role ARN as `changesetRoleToAssumeArn` in `CdkDiffStackWorkflow`.\n\n---\n\n## Usage: CdkDriftDetectionWorkflow\n\n`CdkDriftDetectionWorkflow` creates a single workflow file (default `drift-detection.yml`) that can run on a schedule and via manual dispatch. It generates a helper script at `.github/workflows/scripts/detect-drift.ts` (by default) that uses AWS SDK v3 to run drift detection, write optional machine‑readable JSON, and print an HTML report for the Step Summary.\n\nExample `.projenrc.ts`:\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDriftDetectionWorkflow } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({ github: true, /* ... */ });\n\nnew CdkDriftDetectionWorkflow({\n project,\n workflowName: 'Drift Detection', // optional; file name derived as 'drift-detection.yml'\n schedule: '0 1 * * *', // optional cron\n createIssues: true, // default true; create/update issue when drift detected on schedule\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n // Optional: Node version (default '24.x')\n // nodeVersion: '24.x',\n // Optional: Where to place the helper script (default '.github/workflows/scripts/detect-drift.ts')\n // scriptOutputPath: '.github/workflows/scripts/detect-drift.ts',\n stacks: [\n {\n stackName: 'MyAppStack-Prod',\n driftDetectionRoleToAssumeArn: 'arn:aws:iam::123456789012:role/cdk-drift-role',\n driftDetectionRoleToAssumeRegion: 'us-east-1',\n // failOnDrift: true, // optional (default true)\n },\n ],\n});\n\nproject.synth();\n```\n\n### CdkDriftDetectionWorkflow props\n- `project` (required) — Your Projen project instance.\n- `stacks` (required) — Array of stacks to check.\n- `oidcRoleArn` (required) — Default OIDC role ARN used before chaining into per‑stack drift roles.\n- `oidcRegion` (required) — Default OIDC region.\n- `workflowName` (optional, default `'drift-detection'`) — Human‑friendly workflow name; the file name is derived in kebab‑case.\n- `schedule` (optional) — Cron expression for automatic runs.\n- `createIssues` (optional, default `true`) — When true, scheduled runs will create/update a GitHub issue if drift is detected.\n- `nodeVersion` (optional, default `'24.x'`) — Node.js version for the runner.\n- `scriptOutputPath` (optional, default `'.github/workflows/scripts/detect-drift.ts'`) — Where to write the helper script.\n\n### Per‑stack fields\n- `stackName` (required) — The full CloudFormation stack name.\n- `driftDetectionRoleToAssumeArn` (required) — Role to assume (after OIDC) for making drift API calls.\n- `driftDetectionRoleToAssumeRegion` (required) — Region for that role and API calls.\n- `failOnDrift` (optional, default `true`) — Intended to fail the detection step on drift. The provided script exits with non‑zero when drift is found; the job continues to allow artifact upload and issue creation.\n\n### What gets generated\n- `.github/workflows/<kebab(workflowName)>.yml` — A workflow with one job per stack plus a final summary job.\n- `.github/workflows/scripts/detect-drift.ts` — Helper script that:\n - Starts drift detection and polls until completion\n - Lists non‑`IN_SYNC` resources and builds an HTML report\n - Writes optional JSON to `DRIFT_DETECTION_OUTPUT` when set\n - Prints to stdout and appends to the GitHub Step Summary when available\n\n### Artifacts and summary\n- Each stack job uploads `drift-results-<stack>.json` (if produced).\n- A final `Drift Detection Summary` job downloads all artifacts and prints a consolidated summary.\n\n### Manual dispatch\n- The workflow exposes an input named `stack` with choices including each configured stack and an `all` option.\n- Choose a specific stack to run drift detection for that stack only, or select `all` (or leave the input empty) to run all stacks.\n\nNote: The default workflow does not post PR comments for drift. It can create/update an Issue on scheduled runs when `createIssues` is `true`.\n\n### Post-notification steps (e.g., Slack)\n\nYou can add your own GitHub Action steps to run after the drift detection step for each stack using `postGitHubSteps`.\nProvide your own Slack payload/markdown (this library no longer generates a payload step for you).\n\nOption A: slackapi/slack-github-action (Incoming Webhook, official syntax)\n\n```ts\nnew CdkDriftDetectionWorkflow({\n project,\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n stacks: [/* ... */],\n postGitHubSteps: ({ stack }) => {\n // Build a descriptive name per stack\n const name = `Notify Slack (${stack} post-drift)`;\n const step = {\n name,\n uses: 'slackapi/slack-github-action@v2.1.1',\n // by default, post steps run only when drift is detected; you can override `if`\n if: \"always() && steps.drift.outcome == 'failure'\",\n // Use official inputs: webhook + webhook-type, and a YAML payload with blocks\n with: {\n webhook: '${{ secrets.CDK_NOTIFICATIONS_SLACK_WEBHOOK }}',\n 'webhook-type': 'incoming-webhook',\n payload: [\n 'text: \"** ${{ env.STACK_NAME }} ** has drifted!\"',\n 'blocks:',\n ' - type: \"section\"',\n ' text:',\n ' type: \"mrkdwn\"',\n ' text: \"*Stack:* ${{ env.STACK_NAME }} (region ${{ env.AWS_REGION }}) has drifted:exclamation:\"',\n ' - type: \"section\"',\n ' fields:',\n ' - type: \"mrkdwn\"',\n ' text: \"*Stack ARN*\\\\n${{ steps.drift.outputs.stack-arn }}\"',\n ' - type: \"mrkdwn\"',\n ' text: \"*Issue*\\\\n<${{ github.server_url }}/${{ github.repository }}/issues/${{ steps.issue.outputs.result }}|#${{ steps.issue.outputs.result }}>\"',\n ].join('\\n'),\n },\n };\n return [step];\n },\n});\n```\n\nNote: The Issue link requires `createIssues: true` (default) so that the `Create Issue on Drift` step runs before this Slack step and exposes `steps.issue.outputs.result`. This library orders the steps accordingly.\n\nDetails:\n- `postGitHubSteps` can be:\n - an array of step objects, or\n - a factory function `({ stack }) => step | step[]`.\n- Each step you provide is inserted after the results are uploaded.\n- Default condition: if you do not set `if` on your step, it will default to `always() && steps.drift.outcome == 'failure'`.\n- Available context/env you can use:\n - `${{ env.STACK_NAME }}`, `${{ env.DRIFT_DETECTION_OUTPUT }}`\n - `${{ steps.drift.outcome }}` — success/failure of the detect step\n - `${{ steps.drift.outputs.stack-arn }}` — Stack ARN resolved at runtime\n - `${{ steps.issue.outputs.result }}` — Issue number if the workflow created/found one (empty when not applicable)\n```\n\n## Usage: CdkDriftIamTemplate\n\nEmit an example IAM template you can deploy in your account for the Drift Detection workflow.\n\n### With Projen\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDriftIamTemplate } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({\n // ...\n});\n\nnew CdkDriftIamTemplate({\n project,\n roleName: 'cdk-drift-role',\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n // Optional: custom output path (default: 'cdk-drift-workflow-iam-template.yaml')\n // outputPath: 'infra/cdk-drift-iam.yaml',\n});\n\nproject.synth();\n```\n\nA Projen task is also added:\n\n```bash\nnpx projen deploy-cdkdrift-iam-template -- --parameter-overrides GitHubOIDCRoleArn=... # plus any extra AWS CLI args\n```\n\n### Without Projen (Standalone Generator)\n\n```ts\nimport { CdkDriftIamTemplateGenerator } from '@jjrawlins/cdk-diff-pr-github-action';\nimport * as fs from 'fs';\n\nconst template = CdkDriftIamTemplateGenerator.generateTemplate({\n roleName: 'cdk-drift-role',\n oidcRoleArn: 'arn:aws:iam::123456789012:role/github-oidc-role',\n oidcRegion: 'us-east-1',\n});\n\nfs.writeFileSync('cdk-drift-iam-template.yaml', template);\n\n// Get the deploy command\nconst deployCmd = CdkDriftIamTemplateGenerator.generateDeployCommand('cdk-drift-iam-template.yaml');\nconsole.log('Deploy with:', deployCmd);\n```\n\n### What the template defines\n\n- Parameter `GitHubOIDCRoleArn` with a default from `oidcRoleArn` — the ARN of your existing GitHub OIDC role allowed to assume this drift role.\n- IAM role `CdkDriftRole` with minimal permissions for CloudFormation drift detection operations.\n- Outputs exporting the role name and ARN.\n\n---\n\n## Usage: CdkDiffIamTemplateStackSet (Org-Wide Deployment)\n\n`CdkDiffIamTemplateStackSet` creates a CloudFormation StackSet template for deploying GitHub OIDC provider, OIDC role, and CDK diff/drift IAM roles across an entire AWS Organization. This is the recommended approach for organizations that want to enable CDK diff/drift workflows across multiple accounts.\n\n### Architecture\n\nEach account in your organization gets:\n- **GitHub OIDC Provider** — Authenticates GitHub Actions workflows\n- **GitHubOIDCRole** — Trusts the OIDC provider with repo/branch restrictions\n- **CdkChangesetRole** — For PR change set previews (trusts GitHubOIDCRole)\n- **CdkDriftRole** — For drift detection (trusts GitHubOIDCRole)\n\nThis is a self-contained deployment with **no role chaining required**.\n\n### With Projen\n\n```ts\nimport { awscdk } from 'projen';\nimport { CdkDiffIamTemplateStackSet } from '@jjrawlins/cdk-diff-pr-github-action';\n\nconst project = new awscdk.AwsCdkConstructLibrary({ /* ... */ });\n\nnew CdkDiffIamTemplateStackSet({\n project,\n githubOidc: {\n owner: 'my-org', // GitHub org or username\n repositories: ['infra-repo', 'app-repo'], // Repos allowed to assume roles\n branches: ['main', 'release/*'], // Branch patterns (default: ['*'])\n },\n targetOrganizationalUnitIds: ['ou-xxxx-xxxxxxxx'], // Target OUs\n regions: ['us-east-1', 'eu-west-1'], // Target regions\n // Optional settings:\n // oidcRoleName: 'GitHubOIDCRole', // default\n // changesetRoleName: 'CdkChangesetRole', // default\n // driftRoleName: 'CdkDriftRole', // default\n // roleSelection: StackSetRoleSelection.BOTH, // BOTH, CHANGESET_ONLY, or DRIFT_ONLY\n // delegatedAdmin: true, // Use --call-as DELEGATED_ADMIN (default: true)\n});\n\nproject.synth();\n```\n\nThis creates:\n- `cdk-diff-workflow-stackset-template.yaml` — CloudFormation template\n- Projen tasks for StackSet management\n\n**Projen tasks:**\n```bash\nnpx projen stackset-create # Create the StackSet\nnpx projen stackset-update # Update the StackSet template\nnpx projen stackset-deploy-instances # Deploy to target OUs/regions\nnpx projen stackset-delete-instances # Remove stack instances\nnpx projen stackset-delete # Delete the StackSet\nnpx projen stackset-describe # Show StackSet status\nnpx projen stackset-list-instances # List all instances\n```\n\n### Without Projen (Standalone Generator)\n\nFor non-Projen projects, use `CdkDiffIamTemplateStackSetGenerator` directly:\n\n```ts\nimport {\n CdkDiffIamTemplateStackSetGenerator\n} from '@jjrawlins/cdk-diff-pr-github-action';\nimport * as fs from 'fs';\n\n// Generate the CloudFormation template\nconst template = CdkDiffIamTemplateStackSetGenerator.generateTemplate({\n githubOidc: {\n owner: 'my-org',\n repositories: ['infra-repo'],\n branches: ['main'],\n },\n});\n\n// Write to file\nfs.writeFileSync('stackset-template.yaml', template);\n\n// Get AWS CLI commands for StackSet operations\nconst commands = CdkDiffIamTemplateStackSetGenerator.generateCommands({\n stackSetName: 'cdk-diff-workflow-iam-stackset',\n templatePath: 'stackset-template.yaml',\n targetOrganizationalUnitIds: ['ou-xxxx-xxxxxxxx'],\n regions: ['us-east-1'],\n});\n\nconsole.log('Create StackSet:', commands['stackset-create']);\nconsole.log('Deploy instances:', commands['stackset-deploy-instances']);\n```\n\n### GitHub Actions Workflow (Simplified)\n\nWith per-account OIDC, your workflow is simplified — no role chaining needed:\n\n```yaml\njobs:\n diff:\n runs-on: ubuntu-latest\n permissions:\n id-token: write\n contents: read\n steps:\n - uses: actions/checkout@v4\n\n - uses: aws-actions/configure-aws-credentials@v4\n with:\n role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/GitHubOIDCRole\n aws-region: us-east-1\n\n - name: Assume Changeset Role\n run: |\n CREDS=$(aws sts assume-role \\\n --role-arn arn:aws:iam::${{ env.ACCOUNT_ID }}:role/CdkChangesetRole \\\n --role-session-name changeset-session)\n # Export credentials...\n```\n\n### GitHubOidcConfig options\n\n| Property | Description |\n|----------|-------------|\n| `owner` | GitHub organization or username (required) |\n| `repositories` | Array of repo names, or `['*']` for all repos (required) |\n| `branches` | Array of branch patterns (default: `['*']`) |\n| `additionalClaims` | Extra OIDC claims like `['pull_request', 'environment:production']` |\n\n---\n\n## Testing\n\nThis repository includes Jest tests that snapshot the synthesized outputs from Projen and assert that:\n- Diff workflows are created per stack and contain all expected steps.\n- Drift detection workflow produces one job per stack and a summary job.\n- Only one helper script file is generated per workflow type.\n- Per‑stack OIDC overrides (where supported) are respected.\n- Helpful validation errors are thrown for missing OIDC settings.\n- The IAM template files contain the expected resources and outputs.\n\nRun tests with:\n\n```bash\nyarn test\n```\n\n## Notes\n- This package assumes your repository is configured with GitHub Actions and that you have a GitHub OIDC role configured in AWS.\n- The generated scripts use the AWS SDK v3 for CloudFormation and, where applicable, the GitHub REST API.\n"
3553
3553
  },
3554
3554
  "repository": {
3555
3555
  "type": "git",
@@ -3576,7 +3576,7 @@
3576
3576
  },
3577
3577
  "locationInModule": {
3578
3578
  "filename": "src/CdkDiffIamTemplate.ts",
3579
- "line": 132
3579
+ "line": 440
3580
3580
  },
3581
3581
  "parameters": [
3582
3582
  {
@@ -3590,7 +3590,7 @@
3590
3590
  "kind": "class",
3591
3591
  "locationInModule": {
3592
3592
  "filename": "src/CdkDiffIamTemplate.ts",
3593
- "line": 131
3593
+ "line": 439
3594
3594
  },
3595
3595
  "name": "CdkDiffIamTemplate",
3596
3596
  "symbolId": "src/CdkDiffIamTemplate:CdkDiffIamTemplate"
@@ -3611,7 +3611,7 @@
3611
3611
  "kind": "class",
3612
3612
  "locationInModule": {
3613
3613
  "filename": "src/CdkDiffIamTemplate.ts",
3614
- "line": 19
3614
+ "line": 56
3615
3615
  },
3616
3616
  "methods": [
3617
3617
  {
@@ -3621,7 +3621,7 @@
3621
3621
  },
3622
3622
  "locationInModule": {
3623
3623
  "filename": "src/CdkDiffIamTemplate.ts",
3624
- "line": 110
3624
+ "line": 87
3625
3625
  },
3626
3626
  "name": "generateDeployCommand",
3627
3627
  "parameters": [
@@ -3647,7 +3647,7 @@
3647
3647
  },
3648
3648
  "locationInModule": {
3649
3649
  "filename": "src/CdkDiffIamTemplate.ts",
3650
- "line": 23
3650
+ "line": 60
3651
3651
  },
3652
3652
  "name": "generateTemplate",
3653
3653
  "parameters": [
@@ -3680,22 +3680,76 @@
3680
3680
  "kind": "interface",
3681
3681
  "locationInModule": {
3682
3682
  "filename": "src/CdkDiffIamTemplate.ts",
3683
- "line": 6
3683
+ "line": 7
3684
3684
  },
3685
3685
  "name": "CdkDiffIamTemplateGeneratorProps",
3686
3686
  "properties": [
3687
3687
  {
3688
3688
  "abstract": true,
3689
3689
  "docs": {
3690
+ "stability": "experimental",
3691
+ "summary": "Name for the changeset IAM role."
3692
+ },
3693
+ "immutable": true,
3694
+ "locationInModule": {
3695
+ "filename": "src/CdkDiffIamTemplate.ts",
3696
+ "line": 9
3697
+ },
3698
+ "name": "roleName",
3699
+ "type": {
3700
+ "primitive": "string"
3701
+ }
3702
+ },
3703
+ {
3704
+ "abstract": true,
3705
+ "docs": {
3706
+ "remarks": "When true, githubOidc configuration is required and oidcRoleArn is ignored.\nDefault: false",
3707
+ "stability": "experimental",
3708
+ "summary": "Create a GitHub OIDC role within this template instead of using an existing one."
3709
+ },
3710
+ "immutable": true,
3711
+ "locationInModule": {
3712
+ "filename": "src/CdkDiffIamTemplate.ts",
3713
+ "line": 28
3714
+ },
3715
+ "name": "createOidcRole",
3716
+ "optional": true,
3717
+ "type": {
3718
+ "primitive": "boolean"
3719
+ }
3720
+ },
3721
+ {
3722
+ "abstract": true,
3723
+ "docs": {
3724
+ "remarks": "Required when createOidcRole is true.",
3725
+ "stability": "experimental",
3726
+ "summary": "GitHub OIDC configuration for repo/branch restrictions."
3727
+ },
3728
+ "immutable": true,
3729
+ "locationInModule": {
3730
+ "filename": "src/CdkDiffIamTemplate.ts",
3731
+ "line": 41
3732
+ },
3733
+ "name": "githubOidc",
3734
+ "optional": true,
3735
+ "type": {
3736
+ "fqn": "@jjrawlins/cdk-diff-pr-github-action.GitHubOidcConfig"
3737
+ }
3738
+ },
3739
+ {
3740
+ "abstract": true,
3741
+ "docs": {
3742
+ "remarks": "Only used when oidcRoleArn is provided (external OIDC role).",
3690
3743
  "stability": "experimental",
3691
3744
  "summary": "Region for the OIDC trust condition."
3692
3745
  },
3693
3746
  "immutable": true,
3694
3747
  "locationInModule": {
3695
3748
  "filename": "src/CdkDiffIamTemplate.ts",
3696
- "line": 12
3749
+ "line": 21
3697
3750
  },
3698
3751
  "name": "oidcRegion",
3752
+ "optional": true,
3699
3753
  "type": {
3700
3754
  "primitive": "string"
3701
3755
  }
@@ -3703,15 +3757,17 @@
3703
3757
  {
3704
3758
  "abstract": true,
3705
3759
  "docs": {
3760
+ "remarks": "Required when createOidcRole is false or undefined.",
3706
3761
  "stability": "experimental",
3707
3762
  "summary": "ARN of the existing GitHub OIDC role that can assume this changeset role."
3708
3763
  },
3709
3764
  "immutable": true,
3710
3765
  "locationInModule": {
3711
3766
  "filename": "src/CdkDiffIamTemplate.ts",
3712
- "line": 10
3767
+ "line": 15
3713
3768
  },
3714
3769
  "name": "oidcRoleArn",
3770
+ "optional": true,
3715
3771
  "type": {
3716
3772
  "primitive": "string"
3717
3773
  }
@@ -3719,18 +3775,38 @@
3719
3775
  {
3720
3776
  "abstract": true,
3721
3777
  "docs": {
3778
+ "remarks": "Only used when createOidcRole is true.\nDefault: 'GitHubOIDCRole'",
3722
3779
  "stability": "experimental",
3723
- "summary": "Name for the IAM role."
3780
+ "summary": "Name of the GitHub OIDC role to create."
3724
3781
  },
3725
3782
  "immutable": true,
3726
3783
  "locationInModule": {
3727
3784
  "filename": "src/CdkDiffIamTemplate.ts",
3728
- "line": 8
3785
+ "line": 35
3729
3786
  },
3730
- "name": "roleName",
3787
+ "name": "oidcRoleName",
3788
+ "optional": true,
3731
3789
  "type": {
3732
3790
  "primitive": "string"
3733
3791
  }
3792
+ },
3793
+ {
3794
+ "abstract": true,
3795
+ "docs": {
3796
+ "remarks": "Set to true if the account already has a GitHub OIDC provider.\nOnly used when createOidcRole is true.\nDefault: false",
3797
+ "stability": "experimental",
3798
+ "summary": "Skip creating the OIDC provider (use existing one)."
3799
+ },
3800
+ "immutable": true,
3801
+ "locationInModule": {
3802
+ "filename": "src/CdkDiffIamTemplate.ts",
3803
+ "line": 49
3804
+ },
3805
+ "name": "skipOidcProviderCreation",
3806
+ "optional": true,
3807
+ "type": {
3808
+ "primitive": "boolean"
3809
+ }
3734
3810
  }
3735
3811
  ],
3736
3812
  "symbolId": "src/CdkDiffIamTemplate:CdkDiffIamTemplateGeneratorProps"
@@ -3749,7 +3825,7 @@
3749
3825
  "kind": "interface",
3750
3826
  "locationInModule": {
3751
3827
  "filename": "src/CdkDiffIamTemplate.ts",
3752
- "line": 118
3828
+ "line": 426
3753
3829
  },
3754
3830
  "name": "CdkDiffIamTemplateProps",
3755
3831
  "properties": [
@@ -3762,7 +3838,7 @@
3762
3838
  "immutable": true,
3763
3839
  "locationInModule": {
3764
3840
  "filename": "src/CdkDiffIamTemplate.ts",
3765
- "line": 120
3841
+ "line": 428
3766
3842
  },
3767
3843
  "name": "project",
3768
3844
  "type": {
@@ -3778,7 +3854,7 @@
3778
3854
  "immutable": true,
3779
3855
  "locationInModule": {
3780
3856
  "filename": "src/CdkDiffIamTemplate.ts",
3781
- "line": 122
3857
+ "line": 430
3782
3858
  },
3783
3859
  "name": "outputPath",
3784
3860
  "optional": true,
@@ -5317,6 +5393,6 @@
5317
5393
  "symbolId": "src/CdkDiffIamTemplateStackSet:StackSetRoleSelection"
5318
5394
  }
5319
5395
  },
5320
- "version": "1.1.5",
5321
- "fingerprint": "jhEiebiBnQd0TC/P1r6yX2ojtmoOI75GEhTFUgpYIJw="
5396
+ "version": "1.2.0",
5397
+ "fingerprint": "k2V9wsxAcvcUdeJ88MIQUs52YxCMRGagJv7XBJnWHRo="
5322
5398
  }
package/API.md CHANGED
@@ -19,13 +19,58 @@ const cdkDiffIamTemplateGeneratorProps: CdkDiffIamTemplateGeneratorProps = { ...
19
19
 
20
20
  | **Name** | **Type** | **Description** |
21
21
  | --- | --- | --- |
22
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.roleName">roleName</a></code> | <code>string</code> | Name for the changeset IAM role. |
23
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.createOidcRole">createOidcRole</a></code> | <code>boolean</code> | Create a GitHub OIDC role within this template instead of using an existing one. |
24
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.githubOidc">githubOidc</a></code> | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.GitHubOidcConfig">GitHubOidcConfig</a></code> | GitHub OIDC configuration for repo/branch restrictions. |
22
25
  | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.oidcRegion">oidcRegion</a></code> | <code>string</code> | Region for the OIDC trust condition. |
23
26
  | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.oidcRoleArn">oidcRoleArn</a></code> | <code>string</code> | ARN of the existing GitHub OIDC role that can assume this changeset role. |
24
- | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.roleName">roleName</a></code> | <code>string</code> | Name for the IAM role. |
27
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.oidcRoleName">oidcRoleName</a></code> | <code>string</code> | Name of the GitHub OIDC role to create. |
28
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.skipOidcProviderCreation">skipOidcProviderCreation</a></code> | <code>boolean</code> | Skip creating the OIDC provider (use existing one). |
25
29
 
26
30
  ---
27
31
 
28
- ##### `oidcRegion`<sup>Required</sup> <a name="oidcRegion" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.oidcRegion"></a>
32
+ ##### `roleName`<sup>Required</sup> <a name="roleName" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.roleName"></a>
33
+
34
+ ```typescript
35
+ public readonly roleName: string;
36
+ ```
37
+
38
+ - *Type:* string
39
+
40
+ Name for the changeset IAM role.
41
+
42
+ ---
43
+
44
+ ##### `createOidcRole`<sup>Optional</sup> <a name="createOidcRole" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.createOidcRole"></a>
45
+
46
+ ```typescript
47
+ public readonly createOidcRole: boolean;
48
+ ```
49
+
50
+ - *Type:* boolean
51
+
52
+ Create a GitHub OIDC role within this template instead of using an existing one.
53
+
54
+ When true, githubOidc configuration is required and oidcRoleArn is ignored.
55
+ Default: false
56
+
57
+ ---
58
+
59
+ ##### `githubOidc`<sup>Optional</sup> <a name="githubOidc" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.githubOidc"></a>
60
+
61
+ ```typescript
62
+ public readonly githubOidc: GitHubOidcConfig;
63
+ ```
64
+
65
+ - *Type:* <a href="#@jjrawlins/cdk-diff-pr-github-action.GitHubOidcConfig">GitHubOidcConfig</a>
66
+
67
+ GitHub OIDC configuration for repo/branch restrictions.
68
+
69
+ Required when createOidcRole is true.
70
+
71
+ ---
72
+
73
+ ##### `oidcRegion`<sup>Optional</sup> <a name="oidcRegion" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.oidcRegion"></a>
29
74
 
30
75
  ```typescript
31
76
  public readonly oidcRegion: string;
@@ -35,9 +80,11 @@ public readonly oidcRegion: string;
35
80
 
36
81
  Region for the OIDC trust condition.
37
82
 
83
+ Only used when oidcRoleArn is provided (external OIDC role).
84
+
38
85
  ---
39
86
 
40
- ##### `oidcRoleArn`<sup>Required</sup> <a name="oidcRoleArn" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.oidcRoleArn"></a>
87
+ ##### `oidcRoleArn`<sup>Optional</sup> <a name="oidcRoleArn" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.oidcRoleArn"></a>
41
88
 
42
89
  ```typescript
43
90
  public readonly oidcRoleArn: string;
@@ -47,17 +94,38 @@ public readonly oidcRoleArn: string;
47
94
 
48
95
  ARN of the existing GitHub OIDC role that can assume this changeset role.
49
96
 
97
+ Required when createOidcRole is false or undefined.
98
+
50
99
  ---
51
100
 
52
- ##### `roleName`<sup>Required</sup> <a name="roleName" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.roleName"></a>
101
+ ##### `oidcRoleName`<sup>Optional</sup> <a name="oidcRoleName" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.oidcRoleName"></a>
53
102
 
54
103
  ```typescript
55
- public readonly roleName: string;
104
+ public readonly oidcRoleName: string;
56
105
  ```
57
106
 
58
107
  - *Type:* string
59
108
 
60
- Name for the IAM role.
109
+ Name of the GitHub OIDC role to create.
110
+
111
+ Only used when createOidcRole is true.
112
+ Default: 'GitHubOIDCRole'
113
+
114
+ ---
115
+
116
+ ##### `skipOidcProviderCreation`<sup>Optional</sup> <a name="skipOidcProviderCreation" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateGeneratorProps.property.skipOidcProviderCreation"></a>
117
+
118
+ ```typescript
119
+ public readonly skipOidcProviderCreation: boolean;
120
+ ```
121
+
122
+ - *Type:* boolean
123
+
124
+ Skip creating the OIDC provider (use existing one).
125
+
126
+ Set to true if the account already has a GitHub OIDC provider.
127
+ Only used when createOidcRole is true.
128
+ Default: false
61
129
 
62
130
  ---
63
131
 
@@ -77,15 +145,60 @@ const cdkDiffIamTemplateProps: CdkDiffIamTemplateProps = { ... }
77
145
 
78
146
  | **Name** | **Type** | **Description** |
79
147
  | --- | --- | --- |
148
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.roleName">roleName</a></code> | <code>string</code> | Name for the changeset IAM role. |
149
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.createOidcRole">createOidcRole</a></code> | <code>boolean</code> | Create a GitHub OIDC role within this template instead of using an existing one. |
150
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.githubOidc">githubOidc</a></code> | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.GitHubOidcConfig">GitHubOidcConfig</a></code> | GitHub OIDC configuration for repo/branch restrictions. |
80
151
  | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.oidcRegion">oidcRegion</a></code> | <code>string</code> | Region for the OIDC trust condition. |
81
152
  | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.oidcRoleArn">oidcRoleArn</a></code> | <code>string</code> | ARN of the existing GitHub OIDC role that can assume this changeset role. |
82
- | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.roleName">roleName</a></code> | <code>string</code> | Name for the IAM role. |
153
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.oidcRoleName">oidcRoleName</a></code> | <code>string</code> | Name of the GitHub OIDC role to create. |
154
+ | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.skipOidcProviderCreation">skipOidcProviderCreation</a></code> | <code>boolean</code> | Skip creating the OIDC provider (use existing one). |
83
155
  | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.project">project</a></code> | <code>any</code> | Projen project instance. |
84
156
  | <code><a href="#@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.outputPath">outputPath</a></code> | <code>string</code> | Output path for the template file (default: 'cdk-diff-workflow-iam-template.yaml'). |
85
157
 
86
158
  ---
87
159
 
88
- ##### `oidcRegion`<sup>Required</sup> <a name="oidcRegion" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.oidcRegion"></a>
160
+ ##### `roleName`<sup>Required</sup> <a name="roleName" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.roleName"></a>
161
+
162
+ ```typescript
163
+ public readonly roleName: string;
164
+ ```
165
+
166
+ - *Type:* string
167
+
168
+ Name for the changeset IAM role.
169
+
170
+ ---
171
+
172
+ ##### `createOidcRole`<sup>Optional</sup> <a name="createOidcRole" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.createOidcRole"></a>
173
+
174
+ ```typescript
175
+ public readonly createOidcRole: boolean;
176
+ ```
177
+
178
+ - *Type:* boolean
179
+
180
+ Create a GitHub OIDC role within this template instead of using an existing one.
181
+
182
+ When true, githubOidc configuration is required and oidcRoleArn is ignored.
183
+ Default: false
184
+
185
+ ---
186
+
187
+ ##### `githubOidc`<sup>Optional</sup> <a name="githubOidc" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.githubOidc"></a>
188
+
189
+ ```typescript
190
+ public readonly githubOidc: GitHubOidcConfig;
191
+ ```
192
+
193
+ - *Type:* <a href="#@jjrawlins/cdk-diff-pr-github-action.GitHubOidcConfig">GitHubOidcConfig</a>
194
+
195
+ GitHub OIDC configuration for repo/branch restrictions.
196
+
197
+ Required when createOidcRole is true.
198
+
199
+ ---
200
+
201
+ ##### `oidcRegion`<sup>Optional</sup> <a name="oidcRegion" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.oidcRegion"></a>
89
202
 
90
203
  ```typescript
91
204
  public readonly oidcRegion: string;
@@ -95,9 +208,11 @@ public readonly oidcRegion: string;
95
208
 
96
209
  Region for the OIDC trust condition.
97
210
 
211
+ Only used when oidcRoleArn is provided (external OIDC role).
212
+
98
213
  ---
99
214
 
100
- ##### `oidcRoleArn`<sup>Required</sup> <a name="oidcRoleArn" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.oidcRoleArn"></a>
215
+ ##### `oidcRoleArn`<sup>Optional</sup> <a name="oidcRoleArn" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.oidcRoleArn"></a>
101
216
 
102
217
  ```typescript
103
218
  public readonly oidcRoleArn: string;
@@ -107,17 +222,38 @@ public readonly oidcRoleArn: string;
107
222
 
108
223
  ARN of the existing GitHub OIDC role that can assume this changeset role.
109
224
 
225
+ Required when createOidcRole is false or undefined.
226
+
110
227
  ---
111
228
 
112
- ##### `roleName`<sup>Required</sup> <a name="roleName" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.roleName"></a>
229
+ ##### `oidcRoleName`<sup>Optional</sup> <a name="oidcRoleName" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.oidcRoleName"></a>
113
230
 
114
231
  ```typescript
115
- public readonly roleName: string;
232
+ public readonly oidcRoleName: string;
116
233
  ```
117
234
 
118
235
  - *Type:* string
119
236
 
120
- Name for the IAM role.
237
+ Name of the GitHub OIDC role to create.
238
+
239
+ Only used when createOidcRole is true.
240
+ Default: 'GitHubOIDCRole'
241
+
242
+ ---
243
+
244
+ ##### `skipOidcProviderCreation`<sup>Optional</sup> <a name="skipOidcProviderCreation" id="@jjrawlins/cdk-diff-pr-github-action.CdkDiffIamTemplateProps.property.skipOidcProviderCreation"></a>
245
+
246
+ ```typescript
247
+ public readonly skipOidcProviderCreation: boolean;
248
+ ```
249
+
250
+ - *Type:* boolean
251
+
252
+ Skip creating the OIDC provider (use existing one).
253
+
254
+ Set to true if the account already has a GitHub OIDC provider.
255
+ Only used when createOidcRole is true.
256
+ Default: false
121
257
 
122
258
  ---
123
259