-
Notifications
You must be signed in to change notification settings - Fork 53
Supporting file uploads when running on AWS should allow us not to configure S3_REGION, S3_KEY_ID, and S3_KEY_SECRET #11
Description
Hi there!
We're running Interval Server on AWS ECS and we're currently getting some issues while trying to set up file uploads. The server requires us to pass S3_REGION, S3_KEY_ID, and S3_KEY_SECRET, but that should not be necessary when running it on AWS, as one can leverage using the task IAM role in order to access S3.
Some references:
- https://docs.aws.amazon.com/sdkref/latest/guide/feature-container-credentials.html
- https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html#credentialProviderChain
Current workaround
Our current workaround for this is to patch the code and remove the part where it sets the credentials for S3:
server/src/server/utils/uploads.ts
Lines 38 to 41 in 6e94996
| credentials: { | |
| accessKeyId: env.S3_KEY_ID, | |
| secretAccessKey: env.S3_KEY_SECRET, | |
| }, |
After installing interval-server, we're sed-ing dist/src/server/utils/uploads.js:
sed -i -e '/credentials: {/{N;N;N;d;}' "/usr/local/lib/node_modules/@interval/server/dist/src/server/utils/uploads.js"This simply removes setting the credentials, letting the SDK resolve the credentials dynamically.
Possible solution
Ideally, we should be able to specify only the S3_BUCKET environment variable, and let the other options (S3_REGION, S3_KEY_ID, and S3_KEY_SECRET) be optional. This way, if they're present in the environment, we can use them, otherwise, we let the SDK resolve the credentials dynamically.
Something like this should probably work, although I haven't tested with this code exactly:
diff --git a/src/server/utils/uploads.ts b/src/server/utils/uploads.ts
index e85e31c..0629555 100644
--- a/src/server/utils/uploads.ts
+++ b/src/server/utils/uploads.ts
@@ -1,5 +1,6 @@
import {
S3Client,
+ S3ClientConfig,
PutObjectCommand,
GetObjectCommand,
DeleteObjectsCommand,
@@ -24,6 +25,24 @@ function isS3Available(env: any): env is {
)
}
+function getS3ClientConfig(env: any): S3ClientConfig {
+ const config: S3ClientConfig = {
+ region: env.S3_REGION,
+ }
+
+ if (
+ typeof env.S3_KEY_ID === 'string' &&
+ typeof env.S3_KEY_SECRET === 'string'
+ ) {
+ config.credentials = {
+ accessKeyId: env.S3_KEY_ID,
+ secretAccessKey: env.S3_KEY_SECRET,
+ }
+ }
+
+ return config
+}
+
export const S3_UPLOADS_ENABLED = isS3Available(env)
function getS3Client() {
@@ -33,13 +52,7 @@ function getS3Client() {
)
}
- return new S3Client({
- region: env.S3_REGION,
- credentials: {
- accessKeyId: env.S3_KEY_ID,
- secretAccessKey: env.S3_KEY_SECRET,
- },
- })
+ return new S3Client(getS3ClientConfig(env))
}
export async function getIOPresignedUploadUrl(key: string): Promise<string> {