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:
@@ -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}.`,
|
||||
|
||||
Vendored
+10
-5
@@ -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;
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user