Skip to content

Commit

Permalink
feat(sts): implment action for setting up IAM credentials in workflow…
Browse files Browse the repository at this point in the history
… environment
  • Loading branch information
bryantbiggs committed Jan 1, 2020
1 parent 6ea5d6c commit 6d69c04
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 19 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/main.yml
Expand Up @@ -7,12 +7,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v1
# - name: Configure AWS Credentials
# uses: aws-actions/configure-aws-credentials@v1
# with:
# aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
# aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# aws-region: us-east-1
- name: Configure AWS Credentials
uses: ./packages/sts
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Sync to S3
uses: ./packages/s3
with:
Expand All @@ -28,7 +28,7 @@ jobs:
# - name: Checkout
# uses: actions/checkout@v1
# - name: Configure AWS Credentials
# uses: aws-actions/configure-aws-credentials@v1
# uses: ./packages/sts
# with:
# aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
# aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand Down
2 changes: 1 addition & 1 deletion packages/cloudfront/dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/cloudfront/index.ts
Expand Up @@ -30,7 +30,7 @@ const run = async (): Promise<void> => {
},
};

const cloudfront = new CloudFront({ apiVersion: '2019-03-26' });
const cloudfront = new CloudFront({ apiVersion: '2019-03-26', customUserAgent: 'aws-github-actions-cloudfront' });
const invalidation = await cloudfront.createInvalidation(params).promise();
const invalidationId = invalidation.Invalidation.Id;
core.setOutput('invalidation-id', invalidationId);
Expand Down
20 changes: 10 additions & 10 deletions packages/s3/action.yml
@@ -1,23 +1,23 @@
name: "AWS S3 sync GitHub action"
description: "Sync locally generated artifacts to an S3 bucket"
name: 'AWS S3 sync GitHub action'
description: 'Sync locally generated artifacts to an S3 bucket'
branding:
icon: "cloud"
color: "orange"
icon: 'cloud'
color: 'orange'
inputs:
local-path:
description: "Path to local directory to synchronize with S3"
description: 'Path to local directory to synchronize with S3'
required: true
bucket-name:
description: 'S3 bucket name (not ARN nor URI "s3://xxx", just the bucket name)'
required: true
path-prefix:
description: "S3 prefix path where object(s) will be syncrhonized to"
description: 'S3 prefix path where object(s) will be syncrhonized to'
required: false
default: ""
default: ''
args:
description: 'Optional "awscli s3 sync" cli args - https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html#synopsis'
required: false
default: ""
default: ''
runs:
using: "node12"
main: "dist/index.js"
using: 'node12'
main: 'dist/index.js'
43 changes: 43 additions & 0 deletions packages/sts/action.yml
@@ -0,0 +1,43 @@
name: 'AWS STS credential GitHub action'
description: 'Configure AWS credentials for use with the AWS CLI and AWS SDKs'
branding:
icon: 'cloud'
color: 'orange'
inputs:
aws-region:
description: 'AWS Region to send the request to. If defined, this environment variable overrides the value for the profile setting region'
required: true
aws-access-key-id:
description: 'AWS access key associated with an IAM user or role'
required: true
aws-secret-access-key:
description: 'Specifies the secret key associated with the access key'
required: true
aws-session-token:
description: 'Specifies the session token value that is required if you are using temporary security credentials that you retrieved directly from AWS STS operations'
required: false
mask-aws-account-id:
description: 'Determine if AWS account ID should be hidden from stdout as a secret value'
required: false
assume-role:
description: 'Determine if role should be assumed to generate credentials'
required: false
role-arn:
description: 'The Amazon Resource Name (ARN) of the role to assume'
required: false
role-session-name:
description: 'An identifier for the assumed role session'
required: false
duration-seconds:
description: 'The duration, in seconds, of the role session'
required: false
default: '900'
external-id:
description: 'A unique identifier that might be required when you assume a role in another account'
required: false
outputs:
aws-account-id:
description: 'The AWS account ID for the provided credentials'
runs:
using: 'node12'
main: 'dist/index.js'
1 change: 1 addition & 0 deletions packages/sts/dist/index.js

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions packages/sts/index.ts
@@ -0,0 +1,85 @@
import * as core from '@actions/core';
import * as Sts from 'aws-sdk/clients/sts';

interface AwsEnvValues {
accessKeyId: string;
secretAccessKey: string;
region: string;
sessionToken?: string;
maskAccountId: string;
}

function exportEnvVariables(config: AwsEnvValues): void {
// Export values as environment variables
// https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
core.exportVariable('AWS_ACCESS_KEY_ID', config.accessKeyId);
core.exportVariable('AWS_SECRET_ACCESS_KEY', config.secretAccessKey);
if (config.sessionToken) {
core.exportVariable('AWS_SESSION_TOKEN', config.sessionToken);
}
core.exportVariable('AWS_DEFAULT_REGION', config.region);
core.exportVariable('AWS_REGION', config.region);
}

const run = async (): Promise<void> => {
try {
// Inputs:
const region = core.getInput('aws-region', { required: true });
const accessKeyId = core.getInput('aws-access-key-id', { required: true });
const secretAccessKey = core.getInput('aws-secret-access-key', { required: true });
const sessionToken = core.getInput('aws-session-token', { required: false });
const maskAccountId = core.getInput('mask-aws-account-id', { required: false });
const envValues: AwsEnvValues = {
region,
accessKeyId,
secretAccessKey,
sessionToken,
maskAccountId,
};
exportEnvVariables(envValues);

// Assume role inputs:
const assumeRole = core.getInput('assume-role', { required: false });
const useAssumeRole = assumeRole && assumeRole.toLowerCase() == 'true';
const roleArn = core.getInput('role-arn', { required: useAssumeRole });
const roleSessionName = core.getInput('role-session-name', { required: useAssumeRole });
const durationSeconds = core.getInput('duration-seconds', { required: false });
const parsedDurationSeconds = Math.max(parseInt(durationSeconds), 900);
const externalId = core.getInput('external-id', { required: false });

const sts = new Sts({
apiVersion: '2011-06-15',
customUserAgent: 'aws-github-actions-sts',
});

const params = {
RoleArn: roleArn,
RoleSessionName: roleSessionName,
DurationSecond: parsedDurationSeconds,
ExternalId: externalId,
};

// If assuming role, assume then re-export creds to environment
if (useAssumeRole) {
const role = await sts.assumeRole(params).promise();
envValues.accessKeyId = role.Credentials.AccessKeyId;
envValues.secretAccessKey = role.Credentials.SecretAccessKey;
envValues.sessionToken = role.Credentials.SessionToken;
exportEnvVariables(envValues);
}

// Get AWS account ID
const identity = await sts.getCallerIdentity().promise();
const accountId = identity.Account;
core.setOutput('aws-account-id', accountId);
if (!envValues.maskAccountId || envValues.maskAccountId.toLowerCase() == 'true') {
core.setSecret(accountId);
}
} catch (error) {
core.setFailed(error.message);
}
};

run();

export default run;
18 changes: 18 additions & 0 deletions packages/sts/package.json
@@ -0,0 +1,18 @@
{
"name": "sts",
"version": "0.1.0",
"description": "Configure AWS credentials for use with the AWS CLI and AWS SDKs",
"main": "index.ts",
"dependencies": {
"aws-sdk": "^2.596.0"
},
"devDependencies": {
"@types/node": "^13.1.2"
},
"scripts": {
"compile": "node ../../node_modules/@zeit/ncc/dist/ncc/cli.js build -m",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "clowd.haus",
"license": "Apache-2.0"
}

0 comments on commit 6d69c04

Please sign in to comment.