Coder Social home page Coder Social logo

formidablelabs / terraform-aws-serverless Goto Github PK

View Code? Open in Web Editor NEW
143.0 143.0 19.0 1.05 MB

Infrastructure support for Serverless framework apps, done the right way

Home Page: https://registry.terraform.io/modules/FormidableLabs/serverless/aws

License: MIT License

HCL 100.00%

terraform-aws-serverless's People

Contributors

boygirl avatar cpresler avatar davetapley avatar dependabot[bot] avatar jpdriver avatar kevinmstephens avatar limess avatar paulmarsicloud avatar ryan-roemer avatar tptee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-aws-serverless's Issues

CI policy seems to need ListStackResources

Hi. Not sure if I'm doing something wrong here...

Assumptions

  • A Serverless project with just static content (no service)
  • Use Serverless 1.39.1, serverless-s3-sync, and newish Terraform with 0.1.0 of this module

Steps

  • Set up all Terraform stuff for the ci environment / stage
  • Deploy first time to ci stage as an admin, locally, verifying the stack reported is my-service-name-ci
  • Push changes to CI on the project, which is configured as --stage ci and also to use a user which is a member of the my-service-name-ci-ci group, created by the module..

Expected

Success.

Actual

Getting an error about needing ListStackResources permissions (but these only exist on :

$ yarn sls deploy --stage ci --subfolder "$CI_ENVIRONMENT_NAME_SLUG"
yarn run v1.13.0
...
  Serverless Error ---------------------------------------
 
  User: arn:aws:iam::*********:user/my-user-name is not authorized to perform: cloudformation:ListStackResources on resource: arn:aws:cloudformation:us-east-1:********:stack/my-service-name-ci/*

Feature: Autoload submodules.

  • Check if something like this already exists
  • Figure out how to handle differing options.
  • Consider how outputs of submodules work.
  • Update doc examples to show both.
  • Experiment if a map within a list can work or like a map of nested maps.

Idea:

module "serverless" {
  source = "FormidableLabs/serverless/aws"

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

  modules = [
    "xray" # submodules/xray/
  ]

  plugins = [
    "serverless-s3-sync" # submodules/plugin-serverless-s3-sync/
  ]
}

CI: Set up

  • terraform fmt + failure if changes (?)

Feature: Bootstrap for TF state

This may not be an actual issue, as I'm a bit naive on how this works, but we want to not have to store TF state in git source.

Goals:

  • Terraform state is not in git source.
  • Terraform state is ideally in s3.
  • Add some bootstrap to achieve this. (We'd even consider doing the IAM / resource provisioning for the s3 bootstrap in CloudFormation...)

Feature/Option: SecretsManager

Dependencies:

  • IAM
  • KMS
# TODO(IamPolicyDeveloper): SecretsManager: Read / write secrets
- Effect: Allow
  Action:
  - secretsmanager:PutSecretValue
  - secretsmanager:GetSecretValue
  Resource:
  - !Sub "arn:aws:secretsmanager:${AwsRegion}:${AWS::AccountId}:secret:${ServiceName}/${Stage}/*"
# TODO(IamPolicyAdmin): SecretsManager: Manage secrets
- Effect: Allow
  Action:
  - secretsmanager:DescribeSecret
  - secretsmanager:List*
  Resource:
  # Have to wildcard listing...
  # TODO: ... but could do conditions + tags to limit
  # https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_identity-based-policies.html
  - "*"
- Effect: Allow
  Action:
  - secretsmanager:CreateSecret
  - secretsmanager:DeleteSecret
  Resource:
  - !Sub "arn:aws:secretsmanager:${AwsRegion}:${AWS::AccountId}:secret:${ServiceName}/${Stage}/*"

how to use own serverless.yml?

Hello team, how I can use my own serverless.yml with your module? Or there is no such functionality, and you can use only your predefined yaml?

admin policy needs s3:PutEncryptionConfiguration permission

It seems like the admin role needs the s3:PutEncryptionConfiguration permission as well.

Here is the full list of permissions a serverless-deploying agent might need: https://gist.github.com/ServerlessBot/7618156b8671840a539f405dea2704c8 — might be worth mentioning that your serverless agent may need way more permissions than this module provides by default (depending on which resources are managed with serverless and which are managed with terraform)

from the serverless cli:

  An error occurred: ServerlessDeploymentBucket - API: s3:SetBucketEncryption Access Denied.

note: SetBucketEncryption is actually PutEncryptionConfiguration


A workaround is to simply add that permission to your user/group/policy/whatever ad-hoc.

resource "aws_iam_group_policy" "additional_admin_policy" {
  name  = "tf-${var.service_name}-${var.stage}-additional-admin-policy"
  group = "tf-${var.service_name}-${var.stage}-admin"

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:PutEncryptionConfiguration"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
EOF
}

Feature/Option: Xray

Dependencies:

  • IAM
# TODO(IamPolicyAdmin): Xray: view traces
- Effect: Allow
  Action:
  - xray:BatchGetTraces
  - xray:GetServiceGraph
  - xray:GetTraceGraph
  - xray:GetTraceSummaries
  Resource:
  # Must be wildcard.
  # https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awsxray.html
  # https://docs.aws.amazon.com/xray/latest/devguide/xray-permissions.html#xray-permissions-managedpolicies
  - "*"
# TODO(IamPolicyLambdaExecution): Xray: upload traces
- Effect: Allow
  Action:
  - xray:PutTraceSegments
  - xray:PutTelemetryRecords
  Resource:
  # Must be wildcard.
  # https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awsxray.html
  # https://docs.aws.amazon.com/xray/latest/devguide/xray-permissions.html#xray-permissions-managedpolicies
  - "*"

Feature/Option: KMS

Dependencies:

  • IAM
# TODO(IamPolicyDeveloper): KMS: Use keys
- Effect: Allow
  Action:
  - kms:Encrypt
  - kms:GenerateDataKey
  - kms:Decrypt
  Resource:
  - !GetAtt KmsKey.Arn
# TODO(IamPolicyAdmin): KMS: Manage keys
- Effect: Allow
  Action:
  - kms:Create*
  - kms:Describe*
  - kms:Enable*
  - kms:List*
  - kms:Put*
  - kms:Update*
  - kms:Revoke*
  - kms:Disable*
  - kms:Get*
  - kms:Delete*
  - kms:TagResource
  - kms:UntagResource
  - kms:ScheduleKeyDeletion
  - kms:CancelKeyDeletion
  Resource:
  - !GetAtt KmsKey.Arn
# TODO(IamPolicyLambdaExecution): KMS: Read keys
- Effect: Allow
  Action:
  - kms:Decrypt
  Resource:
  - !GetAtt KmsKey.Arn
# SecretsManager: Read secrets
- Effect: Allow
  Action:
  - secretsmanager:GetSecretValue
  Resource:
  - !Sub "arn:aws:secretsmanager:${AwsRegion}:${AWS::AccountId}:secret:${ServiceName}/${Stage}/*"

Bug: Update serverless and shake out bugs.

Current ones: [email protected]

logs:DescribeLogGroups

  An error occurred: LayersLogGroup - User: arn:aws:iam::819013376994:user/ryan.roemer-developer is not authorized to perform: logs:DescribeLogGroups on resource: arn:aws:logs:us-east-1:819013376994:log-group::log-stream: (Service: AWSLogs; Status Code: 400; Error Code: AccessDeniedException; Request ID: ee5f1c33-9220-11e9-85d0-d97c7a0f13ee).

Looks like that's the "all describe logs" currently defaulted to just admins.

apigateway:PATCH

  User: arn:aws:iam::819013376994:user/ryan.roemer-admin is not authorized to perform: apigateway:PATCH on resource: arn:aws:apigateway:us-east-1::/restapis/mnan08zp19/stages/sandbox

Use different AWS accounts (per stage)

Hi, firstly amazing work, thanks for open sourcing it! 😎

Early on in the README the Concepts section states:

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

It's a known practice to separate stages in to different AWS accounts, e.g:

  • From the Serverless docs

    As an advanced use-case, you can deploy different stages to different accounts by using different profiles per stage.

  • From a top Google result:

    Most companies don’t keep their production infrastructure in the same account as their development infrastructure. This helps reduce any cases where developers accidentally edit/delete production resources.


It'd be great if you could indicate in the README:

  1. Why you decided to implement a single AWS account solution here, and:
  2. Whether there are plans (or willingness to accept work on) adding support for using different AWS accounts (per stage).

SLS tagging CloudFormation issues

From #33


2: my developer account wants the lambda tag permissions as well, though this only errors in cloudformation, not sls cli

image

the tags seem to be cloudformation specific, though I'm not sure how the STAGE tag gets there, since I only inject that into the environment (cf template confirms this)

image

perhaps the cd-lambdas group should have those tag permissions by default?

¯\_(ツ)_/¯

module does not provide outputs

the outputs.tf file is empty, so it's impossible to reference the generated roles/policies/resources, except by duplicating the specific string templating like so, which is fragile

resource "aws_iam_group_policy" "additional_admin_policy" {
  name  = "tf-${var.service_name}-${var.stage}-additional-admin-policy"
  group = "tf-${var.service_name}-${var.stage}-admin"
  # ^ this part implicitly references the group created by the module

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:PutEncryptionConfiguration"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
EOF
}

Feature: Roles / Groups for admin, developer, CI

This is all in the existing source CloudFormation stuff, but basically we should re-examine what we're doing with the following in mind:

  • Identify specific capabilities for admin, developer, ci
  • Consider what's the difference between developer and ci as they're currently the same.
  • Fully document roles / groups for admin, developer, ci
  • Document potential "gotcha's" such as having an admin create new resources in a related serverless (really CloudFormation) config and then needing an admin to delete them, where ci role wouldn't be able to do this. (Can separately ticket this one if needed as it's complicated -- Roemer has some specific experiences in mind).
  • Implement IAM permissions for each.

Parameterise group names

Hi, thanks for what looks like a very useful project!

The existing admin, developer, ci are fairly good / safe names, but it would be good if users could customise (or: translate!) these.

For example, I'd like our ci user group to be called something else on account of an existing ci environment (~=stage here I guess), leading to weird tf-service-name-ci-ci names.

Feature: Make APIGW disable-able

From #33


I don't actually need the apigateway:* permissions on my developer role, since my serverless doesn't expose any routes (I'm using appsync behind the scenes). perhaps that's a good candidate for another module (although most people will probably want it by default so again ¯\_(ツ)_/¯)

Infra: Integrate into reference app.

The primary gate / test of this project being ready is a full integration in our reference app, wherein we:

  • Remove the "aws-${ServiceName}-${Stage}-(admin|developer|ci)" roles from a user
  • Add equivalent "tf-${ServiceName}-${Stage}-(admin|developer|ci)" roles for the user.
  • ... and all actions still work.

Feature/Option: VPC

  • vpc_iam IAM policies
  • vpc_infra The actual VPC (Maybe split out to separate module if bring your own VPC?)
  • vpc includes both vpc_iam and vpc_infra? Or don't do vpc_infra and just document how to do a standard VPC and attach it in README.

Example CloudFormation IAM policies:

Resources:

  IamPolicyDeveloper:
    Properties:
      PolicyDocument:
        Statement:
        # VPC: Get VPC information in order to be able to deploy serverless
        # with `vpc:` configuration references.
        # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-policies-ec2-console.html
        - Effect: "Allow"
          Action:
          - ec2:DescribeSecurityGroups
          - ec2:DescribeVpcs
          - ec2:DescribeSubnets
          Resource:
          # Must be wildcard: https://iam.cloudonaut.io/reference/ec2.html
          - "*"

  IamPolicyLambdaExecution:
    Properties:
      PolicyDocument:
        Statement:
        # VPC: Create the VPC connection
        # https://docs.aws.amazon.com/lambda/latest/dg/vpc.html
        - Effect: "Allow"
          Action:
          - ec2:CreateNetworkInterface
          - ec2:DescribeNetworkInterfaces
          - ec2:DeleteNetworkInterface
          Resource:
          # Must be wildcard: https://iam.cloudonaut.io/reference/ec2.html
          - "*"

[Release][Docs] Root README.md

  • Installation / Usage
  • Add note about minimum TF version.
  • Secrets: AWS_PROFILE or AWS_*_KEYS docs
  • Pairing and using with serverless framework
  • Link / discussion to reference app.
  • The IAM roles approach. Discuss admin, developer, ci
  • Dedicated, hierarchical section on "scenarios"
  • Extending and enhancing: (I’m thinking about customizations for this. If I just export the IAM developer|ci|admin groups and the IAM lambda execution role as outputs, is that sufficient for your use upstream assuming you had a dependency on this new “sls IAM permissions” TF module? Then, you’d likely enhance with aws_iam_group_policy_attachment for the groups and aws_iam_role_policy_attachment for the lambda execution role…)

[DOCUMENT] Feature: Stack / resource naming.

There's often confusion in where resources come from when using serverless (which creates CloudFormation stacks) vs other things support that like this process.

In the reference app, we have specific naming prefixes like:

  • "sls-${ServiceName}-${Stage}": In serverless.yml as service: value.
  • "aws-${ServiceName}-${Stage}": In AWS CloudFormation.

For our new project we should:

  • Support the variables ServiceName and Stage
  • Create a base Terraform name of "tf-${ServiceName}-${Stage}" to signal that these are Terraform managed.
    • Possibly also include the name of this project? (We could even give it a "cool", short name instead of the super boring serverless-iam-terraform)
    • Document this scheme.
  • In documentation, suggest users name their serverless app service "sls-${ServiceName}-${Stage}" with potentially an example.

Export AWS service principals needed for AssumeRole in each module

See:

In #52, we added IAM policies as outputs to allow users to compose an assumable IAM role from those policies. To use these policies in a service role, the user must provide an assume role statement with all of the principals that are allowed to assume the role. Users can't guess which principals to add without inspecting the IAM policies.

In each module, let's add a list of service principals to the outputs like so:

output "service_principals" {
  value = ["lambda.amazonaws.com", "codedeploy.amazonaws.com"]
}

IAM: Lockdown APIGW more.

Our APIGW IAM ARNs are presently:

  # - No partition. TODO_CHECK (has to be AWS?)
  # - No account. TODO_CHECK
  # eg arn:aws:apigateway:us-east-1::/restapis/ibln8d639e/deployments
  sls_apigw_arn = "arn:aws:apigateway:${local.iam_region}:*:/restapis*"

with wildcards because they don't correspond to predictable names. You only get the name after your do a sls deploy, which present s a chicken-vs-egg problem.

Task

  • Research options to limit this more. Potentially doing a post-sls-deploy terraform apply with new variable that limits this more from sls
  • Documentation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.