Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
aws-simple
Advanced tools
A Node.js interface for AWS that allows easy configuration and deployment of simple web apps.
A Node.js interface for AWS that allows easy configuration and deployment of simple web apps.
aws-simple
allows you to easily create and deploy an API Gateway with a custom
domain and optional alias record, host static web resources via S3, and
provision public backend APIs via Lambda. In addition, a local DEV server can be
started to emulate the resulting AWS infrastructure.
For a quick impression, an
example app is available that
consists essentially of a React component that retrieves text from a Lambda
function using a React.useEffect
hook and displays it. Parcel is used for
bundling and TypeScript as language.
In my job I mainly build web apps on top of existing backend/CMS systems. Since many of the frontend tech stacks are similar again and again, I created an abstraction for the AWS CDK/SDK for a faster and easier setup.
Since existing backend/CMS systems are used, an additional persistence layer is rarely required. Therefore, setting up such a layer (e.g. with Amazon DynamoDB) is currently not supported.
I deliberately kept it simple. An app with a more complex setup should be set up manually with the AWS CDK/SDK.
You need to install aws-simple
and aws-cdk
as dependencies, e.g. with:
yarn add --dev aws-simple aws-cdk
npm install --save-dev aws-simple aws-cdk
You need to create an AWS IAM user with programmatic access and the following attached policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["cloudformation:*", "apigateway:*", "s3:*"],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": ["lambda:*"],
"Resource": "arn:aws:lambda:*:*:function:myapp-*"
},
{
"Effect": "Allow",
"Action": ["iam:*"],
"Resource": "arn:aws:iam::*:role/myapp-*"
},
{
"Effect": "Allow",
"Action": ["iam:CreateServiceLinkedRole"],
"Resource": "arn:aws:iam::*:role/aws-service-role/ops.apigateway.amazonaws.com/*"
},
{
"Effect": "Allow",
"Action": ["route53:*"],
"Resource": "arn:aws:route53:::*"
}
]
}
Note: Please replace the app name (myapp
) with your own. All resources
created with CloudFormation have the app name combined with the stack name as a
prefix for their ID such as myapp-mystack-resource-s3-bucket
.
You can install the aws
CLI, e.g. with:
brew install awscli
You can then set up the AWS profile using the credentials from the AWS IAM user you just created:
aws configure
AWS Access Key ID [None]: ********************
AWS Secret Access Key [None]: ****************************************
Default region name [None]: eu-central-1
Default output format [None]: json
As an alternative to using the aws
CLI, you can create the following files
manually:
cat ~/.aws/credentials
[default]
aws_access_key_id = ********************
aws_secret_access_key = ****************************************
cat ~/.aws/config
[default]
output = json
region = eu-central-1
The following two environment variables AWS_PROFILE
and AWS_DEFAULT_PROFILE
are evaluated in the specified order. If neither of the two environment
variables is set, the default
profile is used.
The following two environment variables AWS_ACCESS_KEY_ID
and
AWS_SECRET_ACCESS_KEY
are evaluated. If these are not set, an attempt is made
to read the credentials from the AWS shared credentials file using the AWS
profile. The default location of the file (~/.aws/credentials
) can be
overwritten by setting the environment variable AWS_SHARED_CREDENTIALS_FILE
.
The following two environment variables AWS_REGION
and AWS_DEFAULT_REGION
are evaluated in the specified order. If neither of the two environment
variables is set, an attempt is made to read the region from the AWS config file
using the AWS profile. The default location of the file (~/.aws/config
) can be
overwritten by setting the environment variable AWS_CONFIG_FILE
.
To use the aws-simple
CLI you have to create a top-level node module config
file named aws-simple.config.js
which exports an object compatible to the
AppConfig
interface.
For example, the following app config describes a simple app consisting of a single static HTML file:
exports.default = {
appName: 'myapp',
defaultStackName: 'mystack',
s3Configs: [
{
type: 'file',
publicPath: '/',
localPath: 'dist/app/index.html',
bucketPath: 'index.html'
}
]
};
Note: Different stack names allow multiple stacks of the same app to be
deployed simultaneously. The specified default stack name can be overwritten
with most aws-simple
CLI commands using the --stack-name
CLI option.
Before you can use the AWS CDK you must bootstrap your AWS environment to create the infrastructure that the AWS CDK CLI needs to deploy your AWS CDK app:
npx cdk bootstrap --app 'npx aws-simple create'
Note: This command only needs to be executed once.
npx aws-simple start
Note: When changing the aws-simple
config file, the DEV server must be
restarted. If a bundler such as Parcel or Webpack is used, its watcher must be
started in addition to the DEV server.
Create a stack using the CDK:
npx cdk deploy --app 'npx aws-simple create'
Caution: Re-deploying an already deployed stack (so a stack with the same
name) will remove all tags set with aws-simple tag [options]
.
Upload files to S3:
npx aws-simple upload
Example package.json
scripts:
{
"scripts": {
"deploy": "cdk deploy --app 'npx aws-simple create'",
"postdeploy": "aws-simple upload"
}
}
Note: In a CI pipeline the deploy
script should be called with the additional
argument --require-approval never
, e.g.
npm run deploy --require-approval never
.
TypeScript 2.3 and later support type-checking in *.js
files by adding a
// @ts-check
comment to them:
// @ts-check
/**
* @type {import('aws-simple').AppConfig}
*/
exports.default = {
appName: 'myapp',
defaultStackName: 'mystack'
};
In order to use a custom domain, a public certificate and a public hosted zone must be created manually. You can then configure the custom domain as follows:
exports.default = {
/* ... */
customDomainConfig: {
certificateArn:
'arn:aws:acm:eu-central-1:************:certificate/********-****-****-****-************',
hostedZoneId: '**************',
hostedZoneName: 'example.com',
getAliasRecordName: stackName => stackName
}
};
Note: Different stack names allow multiple stacks of the same app to be
deployed simultaneously. In this case the optional getAliasRecordName
function
is used to give each stack its own URL, for example mystack.example.com
.
You can configure a Lambda function that can be accessed via GET request at the
URL mystack.example.com/endpoint
as follows:
exports.default = {
/* ... */
lambdaConfigs: [
{
httpMethod: 'GET',
publicPath: '/endpoint',
localPath: 'path/to/lambda.js',
// Optional example properties
memorySize: 3008,
timeoutInSeconds: 30,
cachingEnabled: true,
cacheTtlInSeconds: 600,
acceptedParameters: {
foo: {},
bar: {isCacheKey: true},
baz: {required: true},
qux: {isCacheKey: true, required: true}
},
getEnvironment: runtime => ({
BASE_URL:
runtime.type === 'dev'
? `http://localhost:${runtime.port}`
: `https://${runtime.stackName}.example.com`
})
}
]
};
The contents of file path/to/lambda.js
could look like this:
async function handler() {
return {
statusCode: 200,
headers: {'Content-Type': 'application/json'},
body: JSON.stringify('Hello, World!')
};
}
exports.handler = handler;
If the export of the Lambda function node module has a different name than
handler
, this must be explicitly specified in the Lambda configuration:
exports.default = {
/* ... */
lambdaConfigs: [
{
/* ... */
handler: 'myHandler'
}
]
};
Note: If external node modules are to be referenced in the Lambda function node
module, it must be bundled with a bundler such as Webpack (in this case you have
to set the target to node: {target: 'node'}
) to create a single node module
bundle.
You can configure an S3 file that can be accessed via GET request at the URL
mystack.example.com/
as follows:
exports.default = {
/* ... */
s3Configs: [
{
type: 'file',
publicPath: '/',
localPath: 'path/to/file.html',
bucketPath: 'file.html'
}
]
};
Note: The file specified under the local path is loaded into the S3 bucket
associated with the stack using the aws-simple upload [options]
CLI command.
The optionally specified bucket path or, if not specified, the public path is
used as the S3 object key.
You can configure an S3 folder whose contained files can be accessed via GET
request at the URL mystack.example.com/assets/*
as follows:
exports.default = {
/* ... */
s3Configs: [
{
type: 'folder',
publicPath: '/assets',
localPath: 'path/to/folder',
responseHeaders: {
accessControlAllowOrigin: '*',
cacheControl: 'max-age=157680000'
}
}
]
};
Note: All files contained in the folder specified under the local path are
loaded into the S3 bucket associated with the stack using the
aws-simple upload [options]
command. Nested folders are ignored! Thus a
separate S3 Config must be created for each nested folder.
Since the config file is a node module, individual properties can also be set dynamically. For example, you can set the default stack name based on the current hash or tag:
const {isTagDirty, short, tag} = require('git-rev-sync');
exports.default = {
/* ... */
defaultStackName: isTagDirty()
? short(undefined, 8)
: tag().replace(/\./g, '-')
};
You can specify media types (e.g. image/png
, application/octet-stream
, etc.)
to be treated as binary as follows:
exports.default = {
/* ... */
binaryMediaTypes: ['font/woff2']
};
You can enable compression for an API as follows:
exports.default = {
/* ... */
minimumCompressionSizeInBytes: 1000
};
You can set the logging level for the Lambda functions, it affects the log
entries pushed to Amazon CloudWatch Logs. The available levels are OFF
,
ERROR
, and INFO
. Choose ERROR
to write only error-level entries to
CloudWatch Logs, or choose INFO
to include all ERROR
events as well as extra
informational events.
exports.default = {
/* ... */
loggingLevel: 'ERROR'
};
Usage: aws-simple <command> [options]
Commands:
aws-simple create [options] Create a stack using the CDK
aws-simple upload [options] Upload files to S3
aws-simple start [options] Start a local DEV server
aws-simple list [options] List all deployed stacks
aws-simple tag [options] Tag a deployed stack
aws-simple clean-up [options] Clean up old deployed stacks
Options:
--version Show version number [boolean]
-h, --help Show help [boolean]
A Node.js interface for AWS that allows easy configuration and deployment of
simple web apps.
aws-simple create [options]
Create a stack using the CDK
Options:
--version Show version number [boolean]
-h, --help Show help [boolean]
--config The path to the config file
[string] [default: "aws-simple.config.js"]
--stack-name The stack name to be used instead of the default one declared in
the config file [string]
Examples:
npx cdk deploy --app 'npx aws-simple create'
npx cdk deploy --app 'npx aws-simple create --stack-name stage'
aws-simple upload [options]
Upload files to S3
Options:
--version Show version number [boolean]
-h, --help Show help [boolean]
--config The path to the config file
[string] [default: "aws-simple.config.js"]
--stack-name The stack name to be used instead of the default one declared in
the config file [string]
Examples:
npx aws-simple upload
npx aws-simple upload --stack-name stage
aws-simple start [options]
Start a local DEV server
Options:
--version Show version number [boolean]
-h, --help Show help [boolean]
--config The path to the config file
[string] [default: "aws-simple.config.js"]
--port The port to listen on if available, otherwise listen on a random
port [number] [default: 3000]
--cache Enable caching of successful caching-enabled Lambda function
results per request URL [boolean] [default: false]
--verbose Enable logging of successful Lambda function results
[boolean] [default: false]
Examples:
npx aws-simple start
npx aws-simple start --port 3001 --cache
aws-simple list [options]
List all deployed stacks
Options:
--version Show version number [boolean]
-h, --help Show help [boolean]
--config The path to the config file
[string] [default: "aws-simple.config.js"]
Examples:
npx aws-simple list
aws-simple tag [options]
Tag a deployed stack
Options:
--version Show version number [boolean]
-h, --help Show help [boolean]
--config The path to the config file
[string] [default: "aws-simple.config.js"]
--add The tags to add [array]
--remove The tags to remove [array]
--stack-name The stack name to be used instead of the default one declared in
the config file [string]
Examples:
npx aws-simple tag --add release --remove prerelease
npx aws-simple tag --add release --stack-name stage
aws-simple clean-up [options]
Clean up old deployed stacks
Options:
--version Show version number [boolean]
-h, --help Show help [boolean]
--config The path to the config file
[string] [default: "aws-simple.config.js"]
--max-age The maximum age (in days) of a stack, all older stacks will be
deleted [number] [default: 30]
--preserve Optional tags that prevent a stack from being deleted regardless
of its age [array]
--yes The confirmation message will automatically be answered with Yes
[boolean] [default: false]
Examples:
npx aws-simple clean-up
npx aws-simple clean-up --max-age 14 --preserve release
yarn release patch
yarn release minor
yarn release major
After a new release has been created by pushing the tag, it must be published via the GitHub UI. This triggers the final publication to npm.
Copyright (c) 2019, Clemens Akens. Released under the terms of the MIT License.
FAQs
Production-ready AWS website deployment with minimal configuration.
The npm package aws-simple receives a total of 747 weekly downloads. As such, aws-simple popularity was classified as not popular.
We found that aws-simple demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.