Skip to content

Commit

Permalink
Explicitly configure AWS region
Browse files Browse the repository at this point in the history
Make it explicit in our config, code, and documentation.

This became newly and implicitly necessary with the upgrade from the v2
to v3 SDK in b326340.  I didn't notice in development, however, because
region was implicitly sourced from the default profile in my personal
AWS config file.  That config file isn't available in production, of
course, and this resulted in some requests 500-ing with "region not set"
errors upon deploy to Heroku.  I likely could have noticed had I tried
the Heroku review app for the original changes.
  • Loading branch information
tsibley committed Oct 26, 2023
1 parent c7081e8 commit e223cec
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 10 deletions.
3 changes: 3 additions & 0 deletions docs/infrastructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ Deploys to the production app are performed by manually [promoting](https://devc
- `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are tied to the `nextstrain.org` AWS IAM user.
These credentials allow the backend web server limited access to private S3 buckets.

- `AWS_REGION` should be set to the region containing S3 buckets.
This is `us-east-1` for production and testing.

- `REDIS_URL` is provided by the Heroku Redis add-on.
It should not be modified directly.
Our [authentication handlers](../src/authn/index.js) rewrite it at server start to use a secure TLS connection.
Expand Down
39 changes: 29 additions & 10 deletions docs/production.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,28 +73,47 @@ The Node.js server should not be directly accessible on the network. It should
only be accessible via the reverse proxy.


S3
==

Amazon S3 or an alternative S3-compatible object store is required for
Nextstrain Groups data storage.
AWS configuration
=================

The `GROUPS_BUCKET` environment variable or config file field may be used to
override the default bucket name of `nextstrain-groups`.
AWS credentials and a region must be configured for access to services like S3
and Cognito (if using).

The standard AWS credential sources are used, e.g. environment variables,
credential and profile files, instance metadata, etc. Environment variables
are the typical choice, including:
shared credential and config files, instance metadata, etc. Environment
variables are the typical choice, including:

.. parsed-literal::
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
*AWS_SESSION_TOKEN*
*AWS_REGION*
Variable names in italics may not be necessary for all configurations.

Region may be configured with::

AWS_REGION

set in the environment or config file. If not set, the standard AWS config
file, if any, is consulted.

See the AWS SDK for JS v3 documentation for details on the standard
configuration methods for credentials_ and region_.

.. _credentials: https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html
.. _region: https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-region.html


S3
==

Amazon S3 or an alternative S3-compatible object store is required for
Nextstrain Groups data storage.

The `GROUPS_BUCKET` environment variable or config file field may be used to
override the default bucket name of `nextstrain-groups`.

If using an alternative S3-compatible object store, point the server at its
endpoint with::

Expand Down
5 changes: 5 additions & 0 deletions env/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# These outputs are shared by all Terraform configurations (production and
# testing environments) via symlinks. They correspond to required environment
# variables for the nextstrain.org server.
data "aws_region" "current" {}

output "AWS_REGION" {
value = data.aws_region.current.name
}

output "COGNITO_USER_POOL_ID" {
value = module.cognito.COGNITO_USER_POOL_ID
Expand Down
1 change: 1 addition & 0 deletions env/production/config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"AWS_REGION": "us-east-1",
"OIDC_IDP_URL": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Cg5rcTged",
"OAUTH2_CLIENT_ID": "rki99ml8g2jb9sm1qcq9oi5n",
"OAUTH2_CLI_CLIENT_ID": "2vmc93kj4fiul8uv40uqge93m5",
Expand Down
9 changes: 9 additions & 0 deletions src/aws.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import { NodeHttpHandler } from "@smithy/node-http-handler";
import { ProxyAgent } from "proxy-agent";

import { AWS_REGION } from "./config.js";

const agent = new ProxyAgent();

/**
Expand All @@ -14,10 +16,17 @@ const agent = new ProxyAgent();
* AWS SDK v3 doesn't have the concept of a global config like v2 did, so this
* is it.
*
* A region is set to {@link config.AWS_REGION}, which itself comes from the
* AWS_REGION environment variable or our own config file. It may be null, in
* which case the AWS SDK's logic for determining region is used and in
* practice that means the standard AWS config file. See
* {@link https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-region.html}.
*
* HTTP and HTTPS agents are configured to use a proxy agent based on the
* environment (e.g. http_proxy), if any.
*/
export const clientConfig = {
region: AWS_REGION,
requestHandler: new NodeHttpHandler({
httpAgent: agent,
httpsAgent: agent,
Expand Down
15 changes: 15 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,21 @@ function configPath(value) {
}


/**
* AWS region to use for services where it's not otherwise specified.
*
* Currently, this should be the region where the S3 buckets live as the region
* for the Cognito user pool is embedded in its id.
*
* If unspecified, then the AWS SDK's own logic for determining region is used.
* In practice, that means the standard AWS config file (since the SDK also
* looks at the AWS_REGION environment variable).
*
* @type string
*/
export const AWS_REGION = fromEnvOrConfig("AWS_REGION", null);


/**
* Id of our Cognito user pool.
*
Expand Down

0 comments on commit e223cec

Please sign in to comment.