TechDocs/AWS: Enable authentication using env variables and ~/.aws/config shared file

If authentication secrets are provided in app-config.yaml, it will be used. If not, environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION will be used. If not present, ~/.aws/config will be used to read the configs.

https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html
https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-shared.html
https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-region.html
This commit is contained in:
Himanshu Mishra
2021-01-12 11:41:00 +01:00
parent 1c7771871e
commit 16b73697a3
3 changed files with 58 additions and 28 deletions
+12 -5
View File
@@ -66,15 +66,22 @@ techdocs:
# Required when techdocs.publisher.type is set to 'awsS3'. Skip otherwise.
awsS3:
# An API key is required to write to a storage bucket.
# (Required) AWS S3 Bucket Name
bucketName: 'techdocs-storage'
# (Optional) An API key is required to write to a storage bucket.
# If not set, environment variables or aws config file will be used to authenticate.
# https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html
# https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-shared.html
credentials:
accessKeyId:
$env: TECHDOCS_AWSS3_ACCESS_KEY_ID_CREDENTIAL
secretAccessKey:
$env: TECHDOCS_AWSS3_SECRET_ACCESS_KEY_CREDENTIAL
region:
$env: AWSS3_REGION
# AWS S3 Bucket Name
bucketName: 'techdocs-storage'
# (Optional) AWS Region of the bucket.
# If not set, AWS_REGION environment variable or aws config file will be used.
# https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-region.html
region:
$env: AWS_REGION
```
@@ -39,30 +39,47 @@ const streamToString = (stream: Readable): Promise<string> => {
export class AwsS3Publish implements PublisherBase {
static fromConfig(config: Config, logger: Logger): PublisherBase {
let region = null;
let accessKeyId = null;
let secretAccessKey = null;
let bucketName = '';
try {
accessKeyId = config.getString(
'techdocs.publisher.awsS3.credentials.accessKeyId',
);
secretAccessKey = config.getString(
'techdocs.publisher.awsS3.credentials.secretAccessKey',
);
region = config.getOptionalString('techdocs.publisher.awsS3.region');
bucketName = config.getString('techdocs.publisher.awsS3.bucketName');
} catch (error) {
throw new Error(
"Since techdocs.publisher.type is set to 'awsS3' in your app config, " +
'credentials and bucketName are required in techdocs.publisher.awsS3 ' +
'required to authenticate with AWS S3.',
'techdocs.publisher.awsS3.bucketName is required.',
);
}
// Credentials is an optional config. If missing, default AWS environment variables
// or AWS config file in ~/.aws/config will be used to authenticate
// https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html
// https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-shared.html
const credentials = config.getOptionalConfig(
'techdocs.publisher.awsS3.credentials',
);
let accessKeyId = undefined;
let secretAccessKey = undefined;
if (credentials) {
accessKeyId = credentials.getOptionalString('accessKeyId');
secretAccessKey = credentials.getOptionalString('secretAccessKey');
}
// AWS Region is an optional config. If missing, default AWS env variable AWS_REGION
// or AWS config file in ~/.aws/config will be used. But the AWS SDK v3 client needs
// to have the AWS Region information for it to work.
const region = config.getOptionalString('techdocs.publisher.awsS3.region');
const storageClient = new S3({
credentials: { accessKeyId, secretAccessKey },
...(region && { region }),
...(credentials &&
accessKeyId &&
secretAccessKey && {
credentials: {
accessKeyId,
secretAccessKey,
},
}),
...(region && {
region,
}),
});
// Check if the defined bucket exists. Being able to connect means the configuration is good
@@ -75,11 +92,12 @@ export class AwsS3Publish implements PublisherBase {
if (err) {
logger.error(
`Could not retrieve metadata about the AWS S3 bucket ${bucketName}. ` +
'Make sure the AWS project and the bucket exists and the access key located at the path ' +
"techdocs.publisher.awsS3.credentials defined in app config has the role 'Storage Object Creator'. " +
'Refer to https://backstage.io/docs/features/techdocs/using-cloud-storage',
'Make sure the bucket exists. Also make sure that authentication is setup either by ' +
'explicitly defining credentials and region in techdocs.publisher.awsS3 in app config or ' +
'by using environment variables. Refer to https://backstage.io/docs/features/techdocs/using-cloud-storage',
);
throw new Error(`from AWS client library: ${err.message}`);
logger.error(`from AWS client library: ${err.message}`);
throw new Error();
} else {
logger.info(
`Successfully connected to the AWS S3 bucket ${bucketName}.`,
+10 -5
View File
@@ -78,10 +78,13 @@ export interface Config {
*/
awsS3?: {
/**
* Credentials used to access a storage bucket
* (Optional) Credentials used to access a storage bucket.
* If not set, environment variables or aws config file will be used to authenticate.
* https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html
* https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-shared.html
* @visibility secret
*/
credentials: {
credentials?: {
/**
* User access key id
* attr: 'accessKeyId' - accepts a string value
@@ -98,11 +101,13 @@ export interface Config {
/**
* Cloud Storage Bucket Name
* attr: 'bucketName' - accepts a string value
* @visibility secret
* @visibility backend
*/
bucketName: string;
/**
* AWS Region
* (Optional) AWS Region.
* If not set, AWS_REGION environment variable or aws config file will be used.
* https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-region.html
* attr: 'region' - accepts a string value
* @visibility secret
*/
@@ -125,7 +130,7 @@ export interface Config {
/**
* (Required) Cloud Storage Bucket Name
* attr: 'bucketName' - accepts a string value
* @visibility secret
* @visibility backend
*/
bucketName: string;
/**