Skip to content

Commit

Permalink
feat: allow setting oidc session duration, remove extra deprecated se…
Browse files Browse the repository at this point in the history
…ttings (#4)
  • Loading branch information
diranged authored Sep 6, 2023
1 parent 4651559 commit 9792871
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 173 deletions.
55 changes: 17 additions & 38 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 25 additions & 8 deletions src/aws-credentials.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { awsCredentialStep } from './private/aws-credentials';
/** @format */

import { DEFAULT_SESSION_DURATION, awsCredentialStep } from './private/aws-credentials';
import * as github from './workflows-model';

/**
Expand Down Expand Up @@ -54,13 +56,17 @@ class GitHubSecretsProvider extends AwsCredentialsProvider {
region,
accessKeyId: `\${{ secrets.${this.accessKeyId} }}`,
secretAccessKey: `\${{ secrets.${this.secretAccessKey} }}`,
...(this.sessionToken ? {
sessionToken: `\${{ secrets.${this.sessionToken} }}`,
} : undefined),
...(assumeRoleArn ? {
roleToAssume: assumeRoleArn,
roleExternalId: 'Pipeline',
} : undefined),
...(this.sessionToken
? {
sessionToken: `\${{ secrets.${this.sessionToken} }}`,
}
: undefined),
...(assumeRoleArn
? {
roleToAssume: assumeRoleArn,
roleExternalId: 'Pipeline',
}
: undefined),
}),
];
}
Expand All @@ -85,6 +91,14 @@ export interface OpenIdConnectProviderProps {
* @default - no role session name
*/
readonly roleSessionName?: string;

/**
* The maximum time that the session should be valid for. Default is 1800,
* but can be extended for longer deployments or tests. Value is in seconds.
*
* @default DEFAULT_SESSION_DURATION
*/
readonly sessionDuration?: number;
}

/**
Expand All @@ -93,11 +107,13 @@ export interface OpenIdConnectProviderProps {
class OpenIdConnectProvider extends AwsCredentialsProvider {
private readonly gitHubActionRoleArn: string;
private readonly roleSessionName: string | undefined;
private readonly sessionDuration: number;

constructor(props: OpenIdConnectProviderProps) {
super();
this.gitHubActionRoleArn = props.gitHubActionRoleArn;
this.roleSessionName = props.roleSessionName;
this.sessionDuration = props.sessionDuration || DEFAULT_SESSION_DURATION;
}

public jobPermission(): github.JobPermission {
Expand All @@ -116,6 +132,7 @@ class OpenIdConnectProvider extends AwsCredentialsProvider {
region,
roleToAssume: this.gitHubActionRoleArn,
roleSessionName: this.roleSessionName,
sessionDuration: this.sessionDuration,
}),
);

Expand Down
56 changes: 2 additions & 54 deletions src/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,30 +84,6 @@ export interface GitHubWorkflowProps extends PipelineBaseProps {
*/
readonly awsCreds?: AwsCredentialsProvider;

/**
* Names of GitHub repository secrets that include AWS credentials for
* deployment.
*
* @default - `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
*
* @deprecated Use `awsCreds.fromGitHubSecrets()` instead.
*/
readonly awsCredentials?: AwsCredentialsSecrets;

/**
* A role that utilizes the GitHub OIDC Identity Provider in your AWS account.
* If supplied, this will be used instead of `awsCredentials`.
*
* You can create your own role in the console with the necessary trust policy
* to allow gitHub actions from your gitHub repository to assume the role, or
* you can utilize the `GitHubActionRole` construct to create a role for you.
*
* @default - GitHub repository secrets are used instead of OpenId Connect role.
*
* @deprecated Use `awsCreds.fromOpenIdConnect()` instead.
*/
readonly gitHubActionRoleArn?: string;

/**
* Build container options.
*
Expand Down Expand Up @@ -155,8 +131,8 @@ export class GitHubWorkflow extends PipelineBase {
public readonly workflowName: string;
public readonly workflowFile: YamlFile;

private readonly workflowTriggers: github.WorkflowTriggers;
private readonly awsCredentials: AwsCredentialsProvider;
private readonly workflowTriggers: github.WorkflowTriggers;
private readonly buildContainer?: github.ContainerOptions;
private readonly preBuildSteps: github.JobStep[];
private readonly postBuildSteps: github.JobStep[];
Expand All @@ -178,13 +154,12 @@ export class GitHubWorkflow extends PipelineBase {
constructor(scope: Construct, id: string, props: GitHubWorkflowProps) {
super(scope, id, props);

this.awsCredentials = props.awsCreds || AwsCredentials.fromGitHubSecrets();
this.buildContainer = props.buildContainer;
this.preBuildSteps = props.preBuildSteps ?? [];
this.postBuildSteps = props.postBuildSteps ?? [];
this.jobSettings = props.jobSettings;

this.awsCredentials = this.getAwsCredentials(props);

this.workflowPath = props.workflowPath ?? '.github/workflows/deploy.yml';
if (!this.workflowPath.endsWith('.yml') && !this.workflowPath.endsWith('.yaml')) {
throw new Error('workflow file is expected to be a yaml file');
Expand All @@ -203,33 +178,6 @@ export class GitHubWorkflow extends PipelineBase {
this.runner = props.runner ?? github.Runner.UBUNTU_LATEST;
}

/**
* Parse AWS credential configuration from deprecated properties For backwards compatibility.
*/
private getAwsCredentials(props: GitHubWorkflowProps) {
if (props.gitHubActionRoleArn) {
if (props.awsCreds) {
throw new Error('Please provide only one method of authentication (remove githubActionRoleArn)');
}
return AwsCredentials.fromOpenIdConnect({
gitHubActionRoleArn: props.gitHubActionRoleArn,
});
}

if (props.awsCredentials) {
if (props.awsCreds) {
throw new Error('Please provide only one method of authentication (remove awsCredentials)');
}
return AwsCredentials.fromGitHubSecrets({
accessKeyId: 'AWS_ACCESS_KEY_ID',
secretAccessKey: 'AWS_SECRET_ACCESS_KEY',
...props.awsCredentials,
});
}

return props.awsCreds ?? AwsCredentials.fromGitHubSecrets();
}

/**
* Deploy a single Stage by itself with options for further GitHub configuration.
*
Expand Down
16 changes: 14 additions & 2 deletions src/private/aws-credentials.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
/** @format */

import * as github from '../workflows-model';

export const DEFAULT_SESSION_DURATION: number = 30 * 60;

interface AwsCredentialsStepProps {
/**
* @default undefined
Expand Down Expand Up @@ -31,6 +35,14 @@ interface AwsCredentialsStepProps {
*/
readonly roleSessionName?: string;

/**
* The maximum time that the session should be valid for. Default is 1800s,
* but can be extended for longer deployments or tests.
*
* @default DEFAULT_SESSION_DURATION
*/
readonly sessionDuration?: number;

/**
* The AWS Region.
*/
Expand Down Expand Up @@ -64,10 +76,10 @@ export function awsCredentialStep(stepName: string, props: AwsCredentialsStepPro
const params: Record<string, any> = {};

params['aws-region'] = props.region;
params['role-duration-seconds'] = 30 * 60;
(params['role-duration-seconds'] = props.sessionDuration || DEFAULT_SESSION_DURATION),
// Session tagging requires the role to have `sts:TagSession` permissions,
// which CDK bootstrapped roles do not currently have.
params['role-skip-session-tagging'] = props.roleSkipSessionTagging ?? true;
(params['role-skip-session-tagging'] = props.roleSkipSessionTagging ?? true);

params['aws-access-key-id'] = props.accessKeyId;
params['aws-secret-access-key'] = props.secretAccessKey;
Expand Down
Loading

0 comments on commit 9792871

Please sign in to comment.