FormidableLabs / terraform-aws-serverless

Infrastructure support for Serverless framework apps, done the right way
https://registry.terraform.io/modules/FormidableLabs/serverless/aws
MIT License
144 stars 19 forks source link

Terraform Provider Serverless — Formidable, We build the modern web

AWS Serverless Module

Terraform Travis Status Maintenance Status

Get your serverless framework application to AWS, the right way.

Contents

TF Versions

v1 of this module is compatible with Terraform 0.12. Submit pull-requests to master.

v0.8 of this module is compatible with Terraform 0.12 and Terraform 0.11. Submit pull-requests to terraform0.11 branch. This branch is in maintenance mode and will not be updated with new features.

Overview

Getting a serverless application all the way to production in AWS correctly and securely can be quite challenging. In particular, things like:

... lack reasonable guidance to practically achieve in real world applications.

This Terraform module provides a production-ready base of AWS permissions / resources to support a serverless framework application and help manage development / deployment workflows and maintenance. Specifically, it provides:

Concepts

This module allows practical isolation / compartmentalization of privileges within a single AWS account along the following axes:

In this manner, once an AWS superuser deploys a Terraform stack with this module and assigns IAM groups, the rest of the development / devops teams and CI can build and deploy Serverless applications to appropriate cloud targets with the minimum necessary privileges and isolation across services + environments + IAM roles.

Modules

This project provides a core base module that is the minimum that must be used. Once the core is in place, then other optional submodules can be added.

IAM Notes

The IAM permissions are locked down to service + environment + role-specific ARNs as much as is possible within the AWS IAM and Serverless framework constraints. All of our modules/submodules use the same set of base ARNs declared, e.g., in variables.tf and can be considered as follows:

Fully locked down: These ARNs are sufficiently locked to service + environment.

Not locked down: These ARNs could be tighter, but presently are not.

IAM Wildcards: Unfortunately, AWS IAM only allows wildcards ("*") on certain resources, so we cannot actually lock down more. Accordingly, we limit the permissions to only what is needed with a bias towards sticking such permissions in the admin IAM group. Here are our current wildcards:

Core IAM module

X-ray submodule

VPC submodule

Integration

Reference project

Perhaps the easiest place to start is our sample reference project that creates a Serverless framework service named simple-reference that integrates the core module and submodules of this project. The relevant files to review include:

Module integration

Here's a basic integration of the core serverless module:

# variables.tf
variable "stage" {
  description = "The stage/environment to deploy to. Suggest: `sandbox`, `development`, `staging`, `production`."
  default     = "development"
}

# main.tf
provider "aws" {
  region  = "us-east-1"
}

# Core `serverless` IAM support.
module "serverless" {
  source = "FormidableLabs/serverless/aws"

  region       = "us-east-1"
  service_name = "sparklepants"
  stage        = "${var.stage}"

  # (Default values)
  # iam_region          = `*`
  # iam_partition       = `*`
  # iam_account_id      = `AWS_CALLER account`
  # iam_stage           = `STAGE`
  # tf_service_name     = `tf-SERVICE_NAME`
  # sls_service_name    = `sls-SERVICE_NAME`
  # lambda_role_name    = ""
  # role_admin_name     = `admin`
  # role_developer_name = `developer`
  # role_ci_name        = `ci`
  # opt_many_lambdas    = false
  # opt_disable_groups  = false
  # tags = {}
}

That pairs with a serverless.yml configuration:

# This value needs to either be `sls-` + `service_name` module input *or*
# be specified directly as the module input `sls_service_name`, e.g.:
# - `sls-{service_name}`
# - `{sls_service_name}`
service: sls-${self:custom.service}

custom:
  service: "sparklepants"
  stage: ${opt:stage, "development"}

provider:
  name: aws
  # Use the role provided by `terraform-aws-serverless.`
  #
  # **NOTE**: terraform-aws-serverless uses its own Lambda execution role
  # in favor of the Serverless default. It has the same permissions, but
  # allows you to attach IAM policies to it before running `sls deploy`.
  # This prevents failures when trying to run Terraform before deploying
  # your Serverless app.
  role:
    Fn::ImportValue: tf-${self:custom.service}-${self:custom.stage}-LambdaExecutionRoleArn
  runtime: nodejs8.10
  region: "us-east-1"
  stage: ${self:custom.stage}

functions:
  server:
    # ...

layers:
  # Layers defined within a serverless project need be named with a prefix
  # matching the service name in one of the following formats:
  # - `sls-{service_name}-{stage}-{ANYTHING}`
  # - `{sls_service_name}-{stage}-{ANYTHING}`
  vendor:
    path: layers/vendor
    name: sls-${self:custom.service}-${self:custom.stage}-vendor

Let's unpack the parameters a bit more (located in variables.tf):

Most likely, an AWS superuser will be needed to run the Terraform application for these IAM / other resources.

AWS IAM group integration

Once the core module is applied, three IAM groups will be created in the form of ${tf_service_name}-${stage}-(admin|developer|ci). This typically looks something like:

Once these groups exist, an AWS superuser can then attach these groups to AWS individual users as appropriate for the combination of service + stage + role (admin, developer, CI). Or, the IAM group attachments could be controlled via Terraform as well!

The main upshot of this is after attachment, a given AWS user has the minimum necessary privileges for exactly the level of Serverless framework commands they need. Our example Serverless application reference project documentation has many examples of various serverless commands and which IAM group can properly run them.

Maintenance Status

Stable: Formidable is not planning to develop any new features for this project. We are still responding to bug reports and security concerns. We are still welcoming PRs for this project, but PRs that include new features should be small and easy to integrate and should not include breaking changes.