Loading tools/ci-cdk/bin/ci-cdk.ts +6 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,12 @@ import "source-map-support/register"; import * as cdk from "@aws-cdk/core"; import { PullRequestCdnStack } from "../lib/smithy-rs/pull-request-cdn-stack"; import { OidcProviderStack } from "../lib/oidc-provider-stack"; const app = new cdk.App(); new PullRequestCdnStack(app, "smithy-rs-pull-request-cdn-stack", {}); const oidcProviderStack = new OidcProviderStack(app, "oidc-provider-stack", {}); new PullRequestCdnStack(app, "smithy-rs-pull-request-cdn-stack", { githubActionsOidcProvider: oidcProviderStack.githubActionsOidcProvider, }); tools/ci-cdk/lib/constructs/github-oidc-role.ts +2 −17 Original line number Diff line number Diff line Loading @@ -6,23 +6,14 @@ import { FederatedPrincipal, OpenIdConnectProvider, Role } from "@aws-cdk/aws-iam"; import { Construct, Tags } from "@aws-cdk/core"; /// This thumbprint is used to validate GitHub's identity to AWS. /// /// It was obtained by following instructions at: /// https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html /// /// This was done with the initial Idp URL of: /// https://token.actions.githubusercontent.com/.well-known/openid-configuration const GITHUB_CERTIFICATE_THUMBPRINT = "A031C46782E6E6C662C2C87C76DA9AA62CCABD8E"; export interface Properties { name: string; githubOrg: string; githubRepo: string; oidcProvider: OpenIdConnectProvider; } export class GitHubOidcRole extends Construct { public readonly oidcProvider: OpenIdConnectProvider; public readonly oidcRole: Role; constructor(scope: Construct, id: string, properties: Properties) { Loading @@ -32,16 +23,10 @@ export class GitHubOidcRole extends Construct { Tags.of(this).add("construct-name", properties.name); Tags.of(this).add("construct-type", "GitHubOidcRole"); this.oidcProvider = new OpenIdConnectProvider(this, "oidc-provider", { url: "https://token.actions.githubusercontent.com", thumbprints: [GITHUB_CERTIFICATE_THUMBPRINT], clientIds: ["sts.amazonaws.com"], }); this.oidcRole = new Role(this, "oidc-role", { roleName: `${properties.name}-github-oidc-role`, assumedBy: new FederatedPrincipal( this.oidcProvider.openIdConnectProviderArn, properties.oidcProvider.openIdConnectProviderArn, { StringLike: { "token.actions.githubusercontent.com:sub": `repo:${properties.githubOrg}/${properties.githubRepo}:*`, Loading tools/ci-cdk/lib/oidc-provider-stack.ts 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ import { OpenIdConnectProvider } from "@aws-cdk/aws-iam"; import { Construct, StackProps, Stack, Tags } from "@aws-cdk/core"; /// This thumbprint is used to validate GitHub's identity to AWS. /// /// It was obtained by following instructions at: /// https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html /// /// This was done with the initial Idp URL of: /// https://token.actions.githubusercontent.com/.well-known/openid-configuration const GITHUB_CERTIFICATE_THUMBPRINT = "A031C46782E6E6C662C2C87C76DA9AA62CCABD8E"; // There can only be one OIDC provider for a given URL per AWS account, // so put these in their own stack to be shared with other stacks. export class OidcProviderStack extends Stack { public readonly githubActionsOidcProvider: OpenIdConnectProvider; constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); // Tag the resources created by this stack to make identifying resources easier Tags.of(this).add("stack", id); this.githubActionsOidcProvider = new OpenIdConnectProvider(this, "oidc-provider", { url: "https://token.actions.githubusercontent.com", thumbprints: [GITHUB_CERTIFICATE_THUMBPRINT], clientIds: ["sts.amazonaws.com"], }); } } tools/ci-cdk/lib/smithy-rs/pull-request-cdn-stack.ts +8 −2 Original line number Diff line number Diff line Loading @@ -3,16 +3,21 @@ * SPDX-License-Identifier: Apache-2.0. */ import { OpenIdConnectProvider } from "@aws-cdk/aws-iam"; import * as cdk from "@aws-cdk/core"; import { Duration, RemovalPolicy, Tags } from "@aws-cdk/core"; import { Duration, RemovalPolicy, StackProps, Tags } from "@aws-cdk/core"; import { CloudFrontS3Cdn } from "../constructs/cloudfront-s3-cdn"; import { GitHubOidcRole } from "../constructs/github-oidc-role"; export interface Properties extends StackProps { githubActionsOidcProvider: OpenIdConnectProvider; } export class PullRequestCdnStack extends cdk.Stack { public readonly smithyRsOidcRole: GitHubOidcRole; public readonly pullRequestCdn: CloudFrontS3Cdn; constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { constructor(scope: cdk.Construct, id: string, props: Properties) { super(scope, id, props); // Tag the resources created by this stack to make identifying resources easier Loading @@ -22,6 +27,7 @@ export class PullRequestCdnStack extends cdk.Stack { name: "smithy-rs-pull-request", githubOrg: "awslabs", githubRepo: "smithy-rs", oidcProvider: props.githubActionsOidcProvider, }); this.pullRequestCdn = new CloudFrontS3Cdn(this, "pull-request-cdn", { Loading tools/ci-cdk/test/constructs/github-oidc-role.test.ts +5 −9 Original line number Diff line number Diff line Loading @@ -7,25 +7,21 @@ import { Match, Template } from "@aws-cdk/assertions"; import * as cdk from "@aws-cdk/core"; import { Stack } from "@aws-cdk/core"; import { GitHubOidcRole } from "../../lib/constructs/github-oidc-role"; import { OidcProviderStack } from "../../lib/oidc-provider-stack"; test("it should have an OIDC provider and access role", () => { test("it should have an OIDC access role", () => { const app = new cdk.App(); const oidcStack = new OidcProviderStack(app, "oidc-provider-stack", {}); const stack = new Stack(app, "test-stack"); new GitHubOidcRole(stack, "test", { name: "some-name", githubOrg: "some-org", githubRepo: "some-repo", oidcProvider: oidcStack.githubActionsOidcProvider, }); const template = Template.fromStack(stack); // Verify the OIDC provider template.hasResourceProperties("Custom::AWSCDKOpenIdConnectProvider", { ClientIDList: ["sts.amazonaws.com"], ThumbprintList: ["A031C46782E6E6C662C2C87C76DA9AA62CCABD8E"], Url: "https://token.actions.githubusercontent.com", }); // Verify the OIDC role to be assumed template.hasResourceProperties( "AWS::IAM::Role", Loading @@ -42,7 +38,7 @@ test("it should have an OIDC provider and access role", () => { }, Principal: { Federated: { Ref: Match.anyValue(), "Fn::ImportValue": Match.anyValue(), }, }, Effect: "Allow", Loading Loading
tools/ci-cdk/bin/ci-cdk.ts +6 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,12 @@ import "source-map-support/register"; import * as cdk from "@aws-cdk/core"; import { PullRequestCdnStack } from "../lib/smithy-rs/pull-request-cdn-stack"; import { OidcProviderStack } from "../lib/oidc-provider-stack"; const app = new cdk.App(); new PullRequestCdnStack(app, "smithy-rs-pull-request-cdn-stack", {}); const oidcProviderStack = new OidcProviderStack(app, "oidc-provider-stack", {}); new PullRequestCdnStack(app, "smithy-rs-pull-request-cdn-stack", { githubActionsOidcProvider: oidcProviderStack.githubActionsOidcProvider, });
tools/ci-cdk/lib/constructs/github-oidc-role.ts +2 −17 Original line number Diff line number Diff line Loading @@ -6,23 +6,14 @@ import { FederatedPrincipal, OpenIdConnectProvider, Role } from "@aws-cdk/aws-iam"; import { Construct, Tags } from "@aws-cdk/core"; /// This thumbprint is used to validate GitHub's identity to AWS. /// /// It was obtained by following instructions at: /// https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html /// /// This was done with the initial Idp URL of: /// https://token.actions.githubusercontent.com/.well-known/openid-configuration const GITHUB_CERTIFICATE_THUMBPRINT = "A031C46782E6E6C662C2C87C76DA9AA62CCABD8E"; export interface Properties { name: string; githubOrg: string; githubRepo: string; oidcProvider: OpenIdConnectProvider; } export class GitHubOidcRole extends Construct { public readonly oidcProvider: OpenIdConnectProvider; public readonly oidcRole: Role; constructor(scope: Construct, id: string, properties: Properties) { Loading @@ -32,16 +23,10 @@ export class GitHubOidcRole extends Construct { Tags.of(this).add("construct-name", properties.name); Tags.of(this).add("construct-type", "GitHubOidcRole"); this.oidcProvider = new OpenIdConnectProvider(this, "oidc-provider", { url: "https://token.actions.githubusercontent.com", thumbprints: [GITHUB_CERTIFICATE_THUMBPRINT], clientIds: ["sts.amazonaws.com"], }); this.oidcRole = new Role(this, "oidc-role", { roleName: `${properties.name}-github-oidc-role`, assumedBy: new FederatedPrincipal( this.oidcProvider.openIdConnectProviderArn, properties.oidcProvider.openIdConnectProviderArn, { StringLike: { "token.actions.githubusercontent.com:sub": `repo:${properties.githubOrg}/${properties.githubRepo}:*`, Loading
tools/ci-cdk/lib/oidc-provider-stack.ts 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ import { OpenIdConnectProvider } from "@aws-cdk/aws-iam"; import { Construct, StackProps, Stack, Tags } from "@aws-cdk/core"; /// This thumbprint is used to validate GitHub's identity to AWS. /// /// It was obtained by following instructions at: /// https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html /// /// This was done with the initial Idp URL of: /// https://token.actions.githubusercontent.com/.well-known/openid-configuration const GITHUB_CERTIFICATE_THUMBPRINT = "A031C46782E6E6C662C2C87C76DA9AA62CCABD8E"; // There can only be one OIDC provider for a given URL per AWS account, // so put these in their own stack to be shared with other stacks. export class OidcProviderStack extends Stack { public readonly githubActionsOidcProvider: OpenIdConnectProvider; constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); // Tag the resources created by this stack to make identifying resources easier Tags.of(this).add("stack", id); this.githubActionsOidcProvider = new OpenIdConnectProvider(this, "oidc-provider", { url: "https://token.actions.githubusercontent.com", thumbprints: [GITHUB_CERTIFICATE_THUMBPRINT], clientIds: ["sts.amazonaws.com"], }); } }
tools/ci-cdk/lib/smithy-rs/pull-request-cdn-stack.ts +8 −2 Original line number Diff line number Diff line Loading @@ -3,16 +3,21 @@ * SPDX-License-Identifier: Apache-2.0. */ import { OpenIdConnectProvider } from "@aws-cdk/aws-iam"; import * as cdk from "@aws-cdk/core"; import { Duration, RemovalPolicy, Tags } from "@aws-cdk/core"; import { Duration, RemovalPolicy, StackProps, Tags } from "@aws-cdk/core"; import { CloudFrontS3Cdn } from "../constructs/cloudfront-s3-cdn"; import { GitHubOidcRole } from "../constructs/github-oidc-role"; export interface Properties extends StackProps { githubActionsOidcProvider: OpenIdConnectProvider; } export class PullRequestCdnStack extends cdk.Stack { public readonly smithyRsOidcRole: GitHubOidcRole; public readonly pullRequestCdn: CloudFrontS3Cdn; constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { constructor(scope: cdk.Construct, id: string, props: Properties) { super(scope, id, props); // Tag the resources created by this stack to make identifying resources easier Loading @@ -22,6 +27,7 @@ export class PullRequestCdnStack extends cdk.Stack { name: "smithy-rs-pull-request", githubOrg: "awslabs", githubRepo: "smithy-rs", oidcProvider: props.githubActionsOidcProvider, }); this.pullRequestCdn = new CloudFrontS3Cdn(this, "pull-request-cdn", { Loading
tools/ci-cdk/test/constructs/github-oidc-role.test.ts +5 −9 Original line number Diff line number Diff line Loading @@ -7,25 +7,21 @@ import { Match, Template } from "@aws-cdk/assertions"; import * as cdk from "@aws-cdk/core"; import { Stack } from "@aws-cdk/core"; import { GitHubOidcRole } from "../../lib/constructs/github-oidc-role"; import { OidcProviderStack } from "../../lib/oidc-provider-stack"; test("it should have an OIDC provider and access role", () => { test("it should have an OIDC access role", () => { const app = new cdk.App(); const oidcStack = new OidcProviderStack(app, "oidc-provider-stack", {}); const stack = new Stack(app, "test-stack"); new GitHubOidcRole(stack, "test", { name: "some-name", githubOrg: "some-org", githubRepo: "some-repo", oidcProvider: oidcStack.githubActionsOidcProvider, }); const template = Template.fromStack(stack); // Verify the OIDC provider template.hasResourceProperties("Custom::AWSCDKOpenIdConnectProvider", { ClientIDList: ["sts.amazonaws.com"], ThumbprintList: ["A031C46782E6E6C662C2C87C76DA9AA62CCABD8E"], Url: "https://token.actions.githubusercontent.com", }); // Verify the OIDC role to be assumed template.hasResourceProperties( "AWS::IAM::Role", Loading @@ -42,7 +38,7 @@ test("it should have an OIDC provider and access role", () => { }, Principal: { Federated: { Ref: Match.anyValue(), "Fn::ImportValue": Match.anyValue(), }, }, Effect: "Allow", Loading