Skip to content

Commit

Permalink
feat(amplify-provider-awscloudformation): assume role (#669)
Browse files Browse the repository at this point in the history
* resolve env config issue

* minor fix

* through lint

* minor fix

* add multienv support for hosting

* minor fix

* minor fix

* notification delete pinpoint app for env

* minor fix

* feat(amplify-category-hosting): validate hosting bucket name

* feat(amplify-provider-awscloudformation): user agent for  notificaitons

* feat(cli): minor fix

* feat(amplify-provider-awscloudformation): assume role

allow awscloudformation to be configured to assume IAM roles when access aws resources
  • Loading branch information
UnleashedMind committed Jan 8, 2019
1 parent 0e2d2e9 commit c3204bc
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ function console(context) {
if (pinpointApp) {
const { Id, Region } = pinpointApp;
const consoleUrl =
`https://${Region}.console.aws.amazon.com/pinpoint/home/?region=${Region}#/apps/${Id}/manage/channels`;
`https://${Region}.console.aws.amazon.com/pinpoint/home/?region=${Region}#/apps/${Id}/settings`;
opn(consoleUrl, { wait: false });
} else {
context.print.error('Neither notifications nor analytics is anabled in the cloud.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,9 @@ async function promptForProjectConfigConfirmation(context) {
const { awsConfigInfo } = context.exeInfo;

let availableProfiles = [];
const systemConfig = systemConfigManager.getFullConfig();
if (systemConfig) {
availableProfiles = Object.keys(systemConfig);
const namedProfiles = systemConfigManager.getNamedProfiles();
if (namedProfiles) {
availableProfiles = Object.keys(namedProfiles);
}

const useProfileConfirmation = {
Expand Down Expand Up @@ -424,7 +424,7 @@ function persistLocalEnvConfig(context) {
}

function getCurrentConfig(context) {
const awsConfigInfo = {
const projectConfigInfo = {
configLevel: 'general',
config: {},
};
Expand All @@ -438,25 +438,25 @@ function getCurrentConfig(context) {

if (configInfo && configInfo.configLevel !== 'general') {
if (configInfo.useProfile && configInfo.profileName) {
awsConfigInfo.config.useProfile = configInfo.useProfile;
awsConfigInfo.config.profileName = configInfo.profileName;
projectConfigInfo.config.useProfile = configInfo.useProfile;
projectConfigInfo.config.profileName = configInfo.profileName;
} else if (configInfo.awsConfigFilePath && fs.existsSync(configInfo.awsConfigFilePath)) {
const awsSecrets = JSON.parse(fs.readFileSync(configInfo.awsConfigFilePath, 'utf8'));
awsConfigInfo.config.useProfile = false;
awsConfigInfo.config.awsConfigFilePath = configInfo.awsConfigFilePath;
awsConfigInfo.config.accessKeyId = awsSecrets.accessKeyId;
awsConfigInfo.config.secretAccessKey = awsSecrets.secretAccessKey;
awsConfigInfo.config.region = awsSecrets.region;
projectConfigInfo.config.useProfile = false;
projectConfigInfo.config.awsConfigFilePath = configInfo.awsConfigFilePath;
projectConfigInfo.config.accessKeyId = awsSecrets.accessKeyId;
projectConfigInfo.config.secretAccessKey = awsSecrets.secretAccessKey;
projectConfigInfo.config.region = awsSecrets.region;
} else {
throw new Error(`Corrupt file contents in ${configInfoFilePath}`);
}
awsConfigInfo.configLevel = 'project';
projectConfigInfo.configLevel = 'project';
}
} catch (e) {
throw e;
}
}
return awsConfigInfo;
return projectConfigInfo;
}

function updateProjectConfig(context) {
Expand Down Expand Up @@ -485,45 +485,37 @@ function removeProjectConfig(context) {
}
}

async function loadConfiguration(context, awsClient, attatchRegion) {
process.env.AWS_SDK_LOAD_CONFIG = true;
const awsConfigInfo = getCurrentConfig(context);
if (awsConfigInfo.configLevel !== 'general') {
const { config } = awsConfigInfo;
async function loadConfiguration(context, awsClient) {
const projectConfigInfo = getCurrentConfig(context);
if (projectConfigInfo.configLevel === 'project') {
const { config } = projectConfigInfo;
let awsconfig;
if (config.useProfile) {
process.env.AWS_PROFILE = config.profileName;
const credentials = new awsClient.SharedIniFileCredentials({
profile: config.profileName,
});
awsClient.config.credentials = credentials;
awsconfig = await systemConfigManager.getProfiledAwsConfig(config.profileName);
} else {
awsClient.config.loadFromPath(config.awsConfigFilePath);
awsconfig = JSON.parse(fs.readFileSync(config.awsConfigFilePath, 'utf8'));
}
awsClient.config.update(awsconfig);
}
if (attatchRegion) {
awsClient.region = getRegion(awsConfigInfo);
}

return awsClient;
}

function getRegion(awsConfigInfo) {
function resolveRegion() {
// For details of how aws region is set, check the following link
// https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-region.html
if (awsConfigInfo.configLevel === 'general') {
if (process.env.AWS_REGION) {
return process.env.AWS_REGION;
}
if (process.env.AMAZON_REGION) {
return process.env.AMAZON_REGION;
}
const profileName = process.env.AWS_PROFILE || 'default';
return systemConfigManager.getProfile(profileName).region;
let region;
if (process.env.AWS_REGION) {
region = process.env.AWS_REGION;
}
if (process.env.AMAZON_REGION) {
region = process.env.AMAZON_REGION;
}
const { config } = awsConfigInfo;
if (config.useProfile) {
return systemConfigManager.getProfile(config.profileName).region;
if (process.env.AWS_SDK_LOAD_CONFIG) {
const profileName = process.env.AWS_PROFILE || 'default';
region = systemConfigManager.getProfileRegion(profileName);
}
return config.region;
return region;
}

async function newUserCheck(context) {
Expand Down Expand Up @@ -559,22 +551,21 @@ async function newUserCheck(context) {

function scanConfig(context) {
let configSource = getConfigLevel(context);

if (!configSource) {
const systemConfigs = systemConfigManager.getFullConfig();
if (systemConfigs && Object.keys(systemConfigs).length > 0) {
const namedProfiles = systemConfigManager.getNamedProfiles();
if (namedProfiles && Object.keys(namedProfiles).length > 0) {
configSource = 'profile-available';
}
if (systemConfigs && systemConfigs.default) {
if (namedProfiles && namedProfiles.default) {
configSource = 'system';
}
if (process.env.AWS_ACCESS_KEY_ID &&
process.env.AWS_SECRET_ACCESS_KEY &&
(process.env.AWS_REGION || process.env.AMAZON_REGION)) {
configSource = 'envVar';
}
if ((process.env.AWS_PROFILE && systemConfigs &&
systemConfigs[process.env.AWS_PROFILE.trim()])) {
if ((process.env.AWS_PROFILE && namedProfiles &&
namedProfiles[process.env.AWS_PROFILE.trim()])) {
configSource = 'envVar-profile';
}
}
Expand All @@ -585,7 +576,7 @@ function scanConfig(context) {
function getConfigLevel(context) {
let configLevel;
try {
const systemConfigs = systemConfigManager.getFullConfig();
const namedProfiles = systemConfigManager.getNamedProfiles();
const dotConfigDirPath = context.amplify.pathManager.getDotConfigDirPath();
const configInfoFilePath = path.join(dotConfigDirPath, constants.LocalAWSInfoFileName);
if (fs.existsSync(configInfoFilePath)) {
Expand All @@ -596,7 +587,7 @@ function getConfigLevel(context) {
if (envConfigInfo.configLevel === 'general') {
configLevel = 'general';
} else if (envConfigInfo.useProfile && envConfigInfo.profileName &&
systemConfigs && systemConfigs[envConfigInfo.profileName]) {
namedProfiles && namedProfiles[envConfigInfo.profileName]) {
configLevel = 'project';
} else if (envConfigInfo.awsConfigFilePath &&
fs.existsSync(envConfigInfo.awsConfigFilePath)) {
Expand All @@ -615,4 +606,5 @@ module.exports = {
onInitSuccessful,
configure,
loadConfiguration,
resolveRegion,
};
21 changes: 10 additions & 11 deletions packages/amplify-provider-awscloudformation/lib/delete-env.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const aws = require('aws-sdk');
const path = require('path');
const fs = require('fs-extra');
const constants = require('./constants');
const Cloudformation = require('../src/aws-utils/aws-cfn');
const systemConfigManager = require('./system-config-manager');

async function run(context, envName) {
const dotConfigDirPath = context.amplify.pathManager.getDotConfigDirPath();
Expand All @@ -17,27 +17,26 @@ async function run(context, envName) {
throw new Error('AWS credentials missing for the specified environment');
}

const awscfn = getConfiguredAwsCfnClient(awsConfigInfo);
const awscfn = await getConfiguredAwsCfnClient(awsConfigInfo);

return new Cloudformation(context, awscfn)
.then(cfnItem => cfnItem.deleteResourceStack(envName));
}

function getConfiguredAwsCfnClient(awsConfigInfo) {
async function getConfiguredAwsCfnClient(awsConfigInfo) {
process.env.AWS_SDK_LOAD_CONFIG = true;
if (awsConfigInfo.config.useProfile && awsConfigInfo.config.profileName) {
process.env.AWS_PROFILE = awsConfigInfo.config.profileName;
const credentials = new aws.SharedIniFileCredentials({
profile: awsConfigInfo.config.profileName,
});
aws.config.credentials = credentials;
const aws = require('aws-sdk');
let awsconfig;
if (awsConfigInfo.config.useProfile) {
awsconfig = await systemConfigManager.getProfiledAwsConfig(awsConfigInfo.config.profileName);
} else {
aws.config.update({
awsconfig = {
accessKeyId: awsConfigInfo.config.accessKeyId,
secretAccessKey: awsConfigInfo.config.secretAccessKey,
region: awsConfigInfo.config.region,
});
};
}
aws.config.update(awsconfig);
return aws;
}

Expand Down
21 changes: 10 additions & 11 deletions packages/amplify-provider-awscloudformation/lib/initializer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const aws = require('aws-sdk');
const moment = require('moment');
const path = require('path');
const archiver = require('archiver');
Expand All @@ -8,11 +7,12 @@ const Cloudformation = require('../src/aws-utils/aws-cfn');
const S3 = require('../src/aws-utils/aws-s3');
const constants = require('./constants');
const configurationManager = require('./configuration-manager');
const systemConfigManager = require('./system-config-manager');

async function run(context) {
await configurationManager.init(context);
if (!context.exeInfo || (context.exeInfo.isNewEnv)) {
const awscfn = getConfiguredAwsCfnClient(context);
const awscfn = await getConfiguredAwsCfnClient(context);
const initTemplateFilePath = path.join(__dirname, 'rootStackTemplate.json');
const timeStamp = `-${moment().format('YYYYMMDDHHmmss')}`;
const stackName = normalizeStackName(context.exeInfo.projectConfig.projectName + timeStamp);
Expand Down Expand Up @@ -55,22 +55,21 @@ async function run(context) {
}
}

function getConfiguredAwsCfnClient(context) {
async function getConfiguredAwsCfnClient(context) {
const { awsConfigInfo } = context.exeInfo;
process.env.AWS_SDK_LOAD_CONFIG = true;
if (awsConfigInfo.config.useProfile && awsConfigInfo.config.profileName) {
process.env.AWS_PROFILE = awsConfigInfo.config.profileName;
const credentials = new aws.SharedIniFileCredentials({
profile: awsConfigInfo.config.profileName,
});
aws.config.credentials = credentials;
const aws = require('aws-sdk');
let awsconfig;
if (awsConfigInfo.config.useProfile) {
awsconfig = await systemConfigManager.getProfiledAwsConfig(awsConfigInfo.config.profileName);
} else {
aws.config.update({
awsconfig = {
accessKeyId: awsConfigInfo.config.accessKeyId,
secretAccessKey: awsConfigInfo.config.secretAccessKey,
region: awsConfigInfo.config.region,
});
};
}
aws.config.update(awsconfig);
return aws;
}

Expand Down

0 comments on commit c3204bc

Please sign in to comment.