mirror of https://github.com/smithy-lang/smithy-rs
Split CI OIDC provider into its own stack (#948)
This commit is contained in:
parent
34f43d96cf
commit
a273a55e8a
|
@ -7,7 +7,12 @@
|
||||||
import "source-map-support/register";
|
import "source-map-support/register";
|
||||||
import * as cdk from "@aws-cdk/core";
|
import * as cdk from "@aws-cdk/core";
|
||||||
import { PullRequestCdnStack } from "../lib/smithy-rs/pull-request-cdn-stack";
|
import { PullRequestCdnStack } from "../lib/smithy-rs/pull-request-cdn-stack";
|
||||||
|
import { OidcProviderStack } from "../lib/oidc-provider-stack";
|
||||||
|
|
||||||
const app = new cdk.App();
|
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,
|
||||||
|
});
|
||||||
|
|
|
@ -6,23 +6,14 @@
|
||||||
import { FederatedPrincipal, OpenIdConnectProvider, Role } from "@aws-cdk/aws-iam";
|
import { FederatedPrincipal, OpenIdConnectProvider, Role } from "@aws-cdk/aws-iam";
|
||||||
import { Construct, Tags } from "@aws-cdk/core";
|
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 {
|
export interface Properties {
|
||||||
name: string;
|
name: string;
|
||||||
githubOrg: string;
|
githubOrg: string;
|
||||||
githubRepo: string;
|
githubRepo: string;
|
||||||
|
oidcProvider: OpenIdConnectProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GitHubOidcRole extends Construct {
|
export class GitHubOidcRole extends Construct {
|
||||||
public readonly oidcProvider: OpenIdConnectProvider;
|
|
||||||
public readonly oidcRole: Role;
|
public readonly oidcRole: Role;
|
||||||
|
|
||||||
constructor(scope: Construct, id: string, properties: Properties) {
|
constructor(scope: Construct, id: string, properties: Properties) {
|
||||||
|
@ -32,16 +23,10 @@ export class GitHubOidcRole extends Construct {
|
||||||
Tags.of(this).add("construct-name", properties.name);
|
Tags.of(this).add("construct-name", properties.name);
|
||||||
Tags.of(this).add("construct-type", "GitHubOidcRole");
|
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", {
|
this.oidcRole = new Role(this, "oidc-role", {
|
||||||
roleName: `${properties.name}-github-oidc-role`,
|
roleName: `${properties.name}-github-oidc-role`,
|
||||||
assumedBy: new FederatedPrincipal(
|
assumedBy: new FederatedPrincipal(
|
||||||
this.oidcProvider.openIdConnectProviderArn,
|
properties.oidcProvider.openIdConnectProviderArn,
|
||||||
{
|
{
|
||||||
StringLike: {
|
StringLike: {
|
||||||
"token.actions.githubusercontent.com:sub": `repo:${properties.githubOrg}/${properties.githubRepo}:*`,
|
"token.actions.githubusercontent.com:sub": `repo:${properties.githubOrg}/${properties.githubRepo}:*`,
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,16 +3,21 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0.
|
* SPDX-License-Identifier: Apache-2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { OpenIdConnectProvider } from "@aws-cdk/aws-iam";
|
||||||
import * as cdk from "@aws-cdk/core";
|
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 { CloudFrontS3Cdn } from "../constructs/cloudfront-s3-cdn";
|
||||||
import { GitHubOidcRole } from "../constructs/github-oidc-role";
|
import { GitHubOidcRole } from "../constructs/github-oidc-role";
|
||||||
|
|
||||||
|
export interface Properties extends StackProps {
|
||||||
|
githubActionsOidcProvider: OpenIdConnectProvider;
|
||||||
|
}
|
||||||
|
|
||||||
export class PullRequestCdnStack extends cdk.Stack {
|
export class PullRequestCdnStack extends cdk.Stack {
|
||||||
public readonly smithyRsOidcRole: GitHubOidcRole;
|
public readonly smithyRsOidcRole: GitHubOidcRole;
|
||||||
public readonly pullRequestCdn: CloudFrontS3Cdn;
|
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);
|
super(scope, id, props);
|
||||||
|
|
||||||
// Tag the resources created by this stack to make identifying resources easier
|
// Tag the resources created by this stack to make identifying resources easier
|
||||||
|
@ -22,6 +27,7 @@ export class PullRequestCdnStack extends cdk.Stack {
|
||||||
name: "smithy-rs-pull-request",
|
name: "smithy-rs-pull-request",
|
||||||
githubOrg: "awslabs",
|
githubOrg: "awslabs",
|
||||||
githubRepo: "smithy-rs",
|
githubRepo: "smithy-rs",
|
||||||
|
oidcProvider: props.githubActionsOidcProvider,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.pullRequestCdn = new CloudFrontS3Cdn(this, "pull-request-cdn", {
|
this.pullRequestCdn = new CloudFrontS3Cdn(this, "pull-request-cdn", {
|
||||||
|
|
|
@ -7,25 +7,21 @@ import { Match, Template } from "@aws-cdk/assertions";
|
||||||
import * as cdk from "@aws-cdk/core";
|
import * as cdk from "@aws-cdk/core";
|
||||||
import { Stack } from "@aws-cdk/core";
|
import { Stack } from "@aws-cdk/core";
|
||||||
import { GitHubOidcRole } from "../../lib/constructs/github-oidc-role";
|
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 app = new cdk.App();
|
||||||
|
const oidcStack = new OidcProviderStack(app, "oidc-provider-stack", {});
|
||||||
const stack = new Stack(app, "test-stack");
|
const stack = new Stack(app, "test-stack");
|
||||||
|
|
||||||
new GitHubOidcRole(stack, "test", {
|
new GitHubOidcRole(stack, "test", {
|
||||||
name: "some-name",
|
name: "some-name",
|
||||||
githubOrg: "some-org",
|
githubOrg: "some-org",
|
||||||
githubRepo: "some-repo",
|
githubRepo: "some-repo",
|
||||||
|
oidcProvider: oidcStack.githubActionsOidcProvider,
|
||||||
});
|
});
|
||||||
const template = Template.fromStack(stack);
|
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
|
// Verify the OIDC role to be assumed
|
||||||
template.hasResourceProperties(
|
template.hasResourceProperties(
|
||||||
"AWS::IAM::Role",
|
"AWS::IAM::Role",
|
||||||
|
@ -42,7 +38,7 @@ test("it should have an OIDC provider and access role", () => {
|
||||||
},
|
},
|
||||||
Principal: {
|
Principal: {
|
||||||
Federated: {
|
Federated: {
|
||||||
Ref: Match.anyValue(),
|
"Fn::ImportValue": Match.anyValue(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Effect: "Allow",
|
Effect: "Allow",
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Template } from "@aws-cdk/assertions";
|
||||||
|
import * as cdk from "@aws-cdk/core";
|
||||||
|
import { OidcProviderStack } from "../lib/oidc-provider-stack";
|
||||||
|
|
||||||
|
test("it should have an OIDC provider", () => {
|
||||||
|
const app = new cdk.App();
|
||||||
|
const stack = new OidcProviderStack(app, "oidc-provider-stack", {});
|
||||||
|
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",
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue