generator-fastboot
Version:
Spring Boot + Angular/React/Vue in one handy generator
222 lines (200 loc) • 6.6 kB
JavaScript
/**
* Copyright 2013-2021 the original author or authors from the JHipster project.
*
* This file is part of the JHipster project, see https://www.jhipster.tech/
* for more information.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const INSTANCE_PROFILE_ROLE = 'aws-elasticbeanstalk-ec2-role';
const SERVICE_PROFILE_ROLE = 'aws-elasticbeanstalk-service-role';
const AWS_POLICY_ARN = suffix => `arn:aws:iam::aws:policy/${suffix}`;
const AWS_SERVICE_ARN = suffix => `arn:aws:iam::aws:policy/service-role/${suffix}`;
let aws;
let log;
const Iam = (module.exports = function Iam(Aws, generator) {
aws = Aws;
log = generator.log;
});
const createRole = (RoleName, Description, AssumeRolePolicyDocument) => {
const iam = new aws.IAM();
return iam
.createRole({
RoleName,
Description,
AssumeRolePolicyDocument,
})
.promise();
};
const createInstanceProfile = InstanceProfileName => {
const iam = new aws.IAM();
return iam
.createInstanceProfile({
InstanceProfileName,
})
.promise();
};
const addRoleToInstanceProfile = (InstanceProfileName, RoleName) => {
const iam = new aws.IAM();
return iam
.addRoleToInstanceProfile({
InstanceProfileName,
RoleName,
})
.promise();
};
const attachRolePolicy = (PolicyArn, RoleName) => {
const iam = new aws.IAM();
return iam
.attachRolePolicy({
PolicyArn,
RoleName,
})
.promise();
};
const attachServicePolicyToRole = (policySuffix, roleName) => attachRolePolicy(AWS_SERVICE_ARN(policySuffix), roleName);
const attachPolicyToRole = (policySuffix, roleName) => attachRolePolicy(AWS_POLICY_ARN(policySuffix), roleName);
const getRole = RoleName => {
const iam = new aws.IAM();
return iam
.getRole({
RoleName,
})
.promise();
};
const hasRole = roleName =>
getRole(roleName)
.then(() => true)
.catch(err => {
if (err && err.code === 'NoSuchEntity') {
return false;
}
throw err;
});
const hasInstanceProfileName = InstanceProfileName => {
const iam = new aws.IAM();
return iam
.getInstanceProfile({
InstanceProfileName,
})
.promise()
.then(() => true)
.catch(err => {
if (err && err.code === 'NoSuchEntity') {
return false;
}
throw err;
});
};
const hasInstanceProfile = () => hasInstanceProfileName(INSTANCE_PROFILE_ROLE);
const hasInstanceRole = () => hasRole(INSTANCE_PROFILE_ROLE);
const hasServiceProfileRole = () => hasRole(SERVICE_PROFILE_ROLE);
const createInstanceProfileWithAttachment = () =>
createInstanceProfile(INSTANCE_PROFILE_ROLE).then(() => addRoleToInstanceProfile(INSTANCE_PROFILE_ROLE, INSTANCE_PROFILE_ROLE));
const createServiceProfileRoleWithAttachedPolicies = () => {
const roleName = SERVICE_PROFILE_ROLE;
const description = 'Default Elastic Beanstalk Service profile created by JHipster.';
const assumedPolicyDoc = `{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "elasticbeanstalk.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "elasticbeanstalk"
}
}
}
]
}`;
return createRole(roleName, description, assumedPolicyDoc).then(() => {
const policiesToAttach = [
attachServicePolicyToRole('AWSElasticBeanstalkEnhancedHealth', roleName),
attachServicePolicyToRole('AWSElasticBeanstalkService', roleName),
];
return Promise.all(policiesToAttach);
});
};
const createInstanceRoleWithAttachedPolicies = () => {
const roleName = INSTANCE_PROFILE_ROLE;
const description = 'Default Elastic Beanstalk instance profile created by JHipster.';
const assumedPolicyDoc = `{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}`;
return createRole(roleName, description, assumedPolicyDoc).then(() => {
const policiesToAttach = [
attachPolicyToRole('AWSElasticBeanstalkWebTier', roleName),
attachPolicyToRole('AWSElasticBeanstalkWorkerTier', roleName),
attachPolicyToRole('AWSElasticBeanstalkMulticontainerDocker', roleName),
];
return Promise.all(policiesToAttach);
});
};
/**
* Verifies that the Elastic Beanstalk roles have been created in the IAM Account. This is for situations
* where we're deploying to a new/fresh AWS account, and an Elastic Beanstalk application has not been deployed via
* the web-application or CLI.
*
* See [service role info here]{@link https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/iam-servicerole.html}
* and [instance profile info here]{@link https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/iam-instanceprofile.html#iam-instanceprofile-verify}
* @param params
* @param callback
*/
Iam.prototype.verifyRoles = function verifyRoles(params, callback) {
hasInstanceRole()
.then(instanceRole => {
if (!instanceRole) {
log(`Instance role '${INSTANCE_PROFILE_ROLE}' does not exist. Creating based on defaults.`);
return createInstanceRoleWithAttachedPolicies();
}
return instanceRole;
})
.then(() => hasInstanceProfile())
.then(instanceProfileExists => {
if (!instanceProfileExists) {
log(`Instance profile '${INSTANCE_PROFILE_ROLE}' does not exist. Creating based on defaults.`);
return createInstanceProfileWithAttachment();
}
return instanceProfileExists;
})
.then(() => hasServiceProfileRole())
.then(serviceProfileExists => {
if (!serviceProfileExists) {
log(`Service Profile profile '${SERVICE_PROFILE_ROLE}' does not exist. Creating based on defaults.`);
return createServiceProfileRoleWithAttachedPolicies();
}
return serviceProfileExists;
})
.then(() => callback(null, null))
.catch(err => {
callback(
{
message: err.message,
},
null
);
});
};