-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability to configure AWS during shep new (#92)
* add ability to configure AWS during new * refactor configuration of role * add policy to shep created roles * hide IAM task if not being run
- Loading branch information
1 parent
5ceb903
commit d1b15e3
Showing
7 changed files
with
179 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,93 @@ | ||
import { mkdir, writeFile } from '../util/modules/fs' | ||
import { getRole, createRole, attachPolicy } from '../util/aws/iam' | ||
import * as templates from './templates' | ||
import Promise from 'bluebird' | ||
import exec from '../util/modules/exec' | ||
import listr from '../util/modules/listr' | ||
|
||
export default function run (opts) { | ||
const path = opts.path | ||
const rolename = opts.rolename | ||
const region = opts.region | ||
|
||
const tasks = listr([ | ||
let tasks = [ | ||
{ | ||
title: `Setup IAM Role`, | ||
task: setupIam | ||
}, | ||
{ | ||
title: `Create ${path}/`, | ||
task: () => mkdir(path) | ||
}, | ||
{ | ||
title: 'Create Subdirectories', | ||
task: () => createSubDirs(path) | ||
task: createSubDirs | ||
}, | ||
{ | ||
title: 'Create Files', | ||
task: () => createFiles(path) | ||
task: createFiles | ||
}, | ||
{ | ||
title: 'Install Depedencies', | ||
task: () => npmInstall(path) | ||
task: npmInstall | ||
}, | ||
{ | ||
title: 'Initialize Git', | ||
task: () => initGit(path) | ||
task: initGit | ||
} | ||
], opts.quiet) | ||
] | ||
|
||
return tasks.run() | ||
if (!rolename) tasks = tasks.splice(1) | ||
|
||
return listr(tasks, opts.quiet) | ||
.run({ path, rolename, region }) | ||
} | ||
|
||
function createSubDirs (path) { | ||
function setupIam (context) { | ||
const rolename = context.rolename | ||
let newRole = false | ||
|
||
return getRole(rolename) | ||
.catch({ code: 'NoSuchEntity' }, () => { | ||
newRole = true | ||
return createRole(rolename) | ||
}) | ||
.tap(arn => { | ||
context.arn = arn | ||
}) | ||
.then(() => { if (newRole) return attachPolicy(rolename) }) | ||
.catch({ code: 'LimitExceeded' }, () => { | ||
return Promise.reject('Current AWS User does not have sufficient permissions to do this') | ||
}) | ||
} | ||
|
||
function createSubDirs ({ path }) { | ||
return Promise.all([ | ||
mkdir(path + '/functions'), | ||
mkdir(path + '/config') | ||
]) | ||
} | ||
|
||
function createFiles (path) { | ||
function createFiles ({ path, arn, region }) { | ||
const accountId = (/[0-9]{12}(?=:)/.exec(arn) || [ '' ])[0] | ||
|
||
return Promise.all([ | ||
writeFile(path + '/package.json', templates.pkg(path)), | ||
writeFile(path + '/package.json', templates.pkg({ apiName: path, region, accountId })), | ||
writeFile(path + '/config/development.js', templates.env('development')), | ||
writeFile(path + '/config/beta.js', templates.env('beta')), | ||
writeFile(path + '/config/production.js', templates.env('production')), | ||
writeFile(path + '/.gitignore', templates.gitignore()), | ||
writeFile(path + '/README.md', templates.readme(path)), | ||
writeFile(path + '/lambda.json', templates.lambda()), | ||
writeFile(path + '/lambda.json', templates.lambda(arn)), | ||
writeFile(path + '/api.json', templates.api(path)), | ||
writeFile(path + '/webpack.config.js', templates.webpack()) | ||
]) | ||
} | ||
|
||
function npmInstall (path) { | ||
function npmInstall ({ path }) { | ||
return exec('npm', ['install'], { cwd: path }) | ||
} | ||
|
||
function initGit (path) { | ||
function initGit ({ path }) { | ||
return exec('git', ['init'], { cwd: path }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import AWS from './' | ||
import { lambdaRole } from '../../new/templates' | ||
|
||
export function createRole (name) { | ||
const iam = new AWS.IAM() | ||
const params = { | ||
RoleName: name, | ||
AssumeRolePolicyDocument: lambdaRole() | ||
} | ||
|
||
return iam.createRole(params).promise().get('Role').get('Arn') | ||
} | ||
|
||
export function getRole (name) { | ||
const iam = new AWS.IAM() | ||
const params = { RoleName: name } | ||
|
||
return iam.getRole(params).promise().get('Role').get('Arn') | ||
} | ||
|
||
export function attachPolicy (name) { | ||
const iam = new AWS.IAM() | ||
const params = { | ||
PolicyArn: 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', | ||
RoleName: name | ||
} | ||
|
||
return iam.attachRolePolicy(params).promise() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import test from 'ava' | ||
import Promise from 'bluebird' | ||
import { fs } from '../helpers/fs' | ||
import { exec } from '../helpers/exec' | ||
import td from '../helpers/testdouble' | ||
|
||
const rolename = 'fooRole' | ||
const region = 'us-east-1' | ||
const path = 'foo-path' | ||
const accountId = '123412341234' | ||
const roleArn = `arn:aws:iam:${accountId}:role/${rolename}` | ||
const templates = td.replace('../../src/new/templates') | ||
const iam = td.replace('../../src/util/aws/iam') | ||
td.when(iam.getRole(rolename)).thenReturn(Promise.reject({ code: 'NoSuchEntity' })) | ||
td.when(iam.createRole(rolename)).thenReturn(Promise.resolve(roleArn)) | ||
|
||
test.before(() => { | ||
const shep = require('../../src/index') | ||
return shep.new({ region, rolename, path, quiet: true }) | ||
}) | ||
|
||
test('Creates role and writes configured templates', () => { | ||
td.verify(fs.writeFile(), { ignoreExtraArgs: true }) | ||
td.verify(exec(), { ignoreExtraArgs: true }) | ||
td.verify(templates.pkg({ apiName: path, region, accountId })) | ||
td.verify(templates.lambda(roleArn)) | ||
td.verify(iam.attachPolicy(rolename)) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import test from 'ava' | ||
import Promise from 'bluebird' | ||
import { fs } from '../helpers/fs' | ||
import { exec } from '../helpers/exec' | ||
import td from '../helpers/testdouble' | ||
|
||
const rolename = 'fooRole' | ||
const region = 'us-east-1' | ||
const path = 'foo-path' | ||
const accountId = '123412341234' | ||
const roleArn = `arn:aws:iam:${accountId}:role/${rolename}` | ||
const templates = td.replace('../../src/new/templates') | ||
const iam = td.replace('../../src/util/aws/iam') | ||
td.when(iam.getRole(rolename)).thenReturn(Promise.resolve(roleArn)) | ||
|
||
test.before(() => { | ||
const shep = require('../../src/index') | ||
return shep.new({ region, rolename, path, quiet: true }) | ||
}) | ||
|
||
test('If role is found, no role is created', () => { | ||
td.verify(iam.createRole(), { times: 0, ignoreExtraArgs: true }) | ||
td.verify(iam.attachPolicy(), { times: 0, ignoreExtraArgs: true }) | ||
td.verify(fs.writeFile(), { ignoreExtraArgs: true }) | ||
td.verify(exec(), { ignoreExtraArgs: true }) | ||
}) | ||
|
||
test('Wrote configured templates', () => { | ||
td.verify(templates.pkg({ apiName: path, region, accountId })) | ||
td.verify(templates.lambda(roleArn)) | ||
}) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters