Giter Site home page Giter Site logo

ematipico / terraform-nextjs-plugin Goto Github PK

View Code? Open in Web Editor NEW
52.0 3.0 5.0 13.59 MB

A plugin to generate terraform configuration for Nextjs 8 and 9

License: MIT License

JavaScript 95.93% HCL 1.21% TypeScript 2.86%
terraform nextjs plugin serverless api-gateway lambda aws terraform-nextjs-plugin cli

terraform-nextjs-plugin's Introduction

Terraform nextjs plugin

A plugin to generate terraform configuration from nextjs pages

Build Status Codacy Badge npm Conventional Commits codecov

The reason

Nextjs supports serverless pages, where it creates files that can be used by some lambdas to render the pages. Unfortunately, here you are left alone. So here a solution for your troubles.

Installation

npm i --save-dev @ematipico/terraform-nextjs-plugin

Or

yarn add --dev @ematipico/terraform-nextjs-plugin

This package requires at least Next v8.

Usage

terranext --provider=AWS

This library supports cosmiconfig: you just need to have a file called terranextrc that matches the criteria. This repository has one.

Via CLI

You can use the simple CLI available. At moment you can't pass the routes parameter, you will need to use the config object or use the API.

Using the CLI will automatically emit the configuration files.

Arguments passed via CLI will override the ones that are defined inside the config file.

terranext --provider=AWS --gateway-key=CustomKey --next-dir-app=../../nextjs-project/

Or you can use the aliases:

terranext --provider=AWS -g=CustomKey -p=../../nextjs-project/

Help section


Usage
  $ terranext

Options
  --gateway-key, -g     The API Gateway key of the project. Default is "Terranext"
  --next-app-dir, -d    The path that Terraform CLI has to follow to reach the nextjs project.
  --provider            The Cloud provider to use when exporting the configuration
  --env				    A way for passing environment variables to the lambdas


Examples
  $ terranext
  $ terranext --gateway-key=CustomKey --next-app-dir=../../nextjs-project/
  $ terranext --provider=AWS --next-app-dir=../../nextjs-project/
  $ terranext -g=CustomKey -d=../../nextjs-project/
  $ terranext --env="DEBUG,express:*" --env="API_KEY,1234"

Via API

const generateResources = require("@ematipico/terraform-nextjs-plugin");

const configuration = {
	gatewayKey: "AmazingWebsite",
	lambdaPath: "../../project/build",
	provider: "AWS",
	env: [
		{
			key: "KEY",
			value: "2940"
		}
	]
};

const resources = generateResources(configuration); // inside resources you have the terraform json configuration
generateResources(configuration, true); // it creates two files

If the second argument is a boolean and it's true, the library will create two files:

  • gateway.terraform.tf.json
  • lambdas.terraform.tf.json

Having a suffix with .tf. will tell automatically to terraform that should be validated and planned. It will be up to you to consume them in a proper way.

Configuration

Name Type Default Description
gatewayKey string Terranext A name that will be prefixed to your resources. Usually it's the project name. Default value: Terranext.
provider string Must be provided The Cloud Provider. Based on the value, a different configuration will be exported. Supported providers: AWS
nextAppDir string Must be provided This is the path where your Next.js project is. Usually you will run terraform CLI from a different project/folder. So you need to tell terraform where this folder is. The library will take care of the rest. Default value: "./"
routes Array<Mapping>, Mapping Optional This is the structure of the routes that describe your pages.
env Array<Env> Optional Environments passed via CLI have to be split using ,: --env="KEY,VALUE". When using the API, you always have to pass an array of objects { key: "MyKeyName", "value": "MyKeyValue" }. Environment variables are applied to all the lambdas
nodeVersion 10 or 12 10 Runtime to use

Mapping explained

These mappings are only needed if you have custom routes. If you don't, routes is not needed as this library is able to create mappings from the files that Nextjs generates.

Let's say we want to describe the following URLs:

  • /about-us/contacts
  • /about-us/the-company
  • /blog/first-blog-post
  • /blog/second-blog-post
  • /credits?hideComments: here, hideComments is not mandatory. If it is mandatory, it will be marked true in the configuration
const routes = [
	{
		prefix: "/about-us",
		mappings: [
			{
				route: "/contacts", // the URL
				page: "/companyContacts" // the nextjs file, inside pages folder, that is responsible to render this page
			},
			{
				route: "/the-company",
				page: "/aboutTheCompany"
			}
		]
	},
	{
		prefix: "",
		mappings: [
			{
				route: "/blog/:url",
				page: "/blogPost"
			},
			{
				route: "/credits",
				page: "/credits",
				params: {
					hideComments: false
				}
			}
		]
	}
];

Providers

At the moment the project supports only AWS but it's up to support more providers in the future.

AWS

Once you generate the resource files, you will need to consume them. Also, you will need to create the following resource:

resource "aws_api_gateway_rest_api" "CustomKey" {
  name        = "WebApi"
  description = "Web API"
}

locals {
  groupname = "WebApi"
  lambda_iam_role = "arn:aws:iam::202020202020:role/lambda_execution_role"
  aws_region = "${data.aws_region.current.name}"
}

Please check the integration testing to see how to consume the configuration.

terraform-nextjs-plugin's People

Contributors

dependabot-preview[bot] avatar ematipico avatar jariz avatar michareiser avatar papile avatar xiaohanxu-nick 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

Watchers

 avatar  avatar  avatar

terraform-nextjs-plugin's Issues

[Break] Refactor how query params are handled

At the moment query parameters are handled in a dreadful way. A new way would be nicer:

const routes = {
	prefix: '',
	mappings: [
		{
			page: '/myPage',
			route: '/content',
			params: [ 'showComments', 'hideComments', 'etc.' ]
			}
		}
	]
}

Lambda Handler not being found when viewing the generated API Stage

Issue

NodeJS 8.10 Handler 'render' missing on module 'contact'
NodeJS 10.x Contact.render is undefined or not exported

Expected Behavior

Page to be displayed.

Actual Behavior

Error message is shown and stack is logged to cloudwatch.

Steps to Reproduce the Problem

  1. Generate Example as shown in the integration section of the repository.
  2. Do a terraform apply
  3. Go to the generated link from the API Gateway and navigate to one of the routes.
  4. Review the cloudwatch log generated.

Specifications

  • Next 9.1.2
  • React 16.11.0
  • React-dom 16.11
  • Node 8.10 (Did try 10.x with updating the lambdas too)
  • Terraform v0.11.15
  • Version: latest
  • Platform: Ubuntu / AWS
  • Subsystem:

Example of lambda contents:

  • Contact.js
    "\n\nconst page = require('./contact.original.js');\nconst http = require('http')\n\nexports.render = (event, context, callback) => {\n\tconst server = new http.Server((req, res) => page.render(req, res));\n\tserver.listen(3000);\n};\n\n\n"

I have set the nextJs config to be serverless but it could be that it is not picking it up.

[BREAKING CHANGE] Drop node v8

As per title, this is a breaking change. The library will drop support of node v8 inside its source code AND inside the lambda configuration

[Feat] Better CLI

CLI is not working as it should be yet.

At the moment it reads from a config file but options should also be passed via CLI

[Feat] More configuration

Possibility to configure:

  • runtime of the lambda (now it's hardcoded to nodejs8.10)
  • memory_size of the lambda
  • timeout of the lambda

Integration Example is missing critical setup information

As the title suggests.

When building the terraform files using the build.js file created many resources are created that if ran are not created. As a result of that when creating those terraform resources to match up with the desired routes it is not clear what should to where.

For example data.archive_file.packLambda-index resource is required but it is not clear what file this resource should point to. Unfortunately this repository seems to be missing a lot of initial set up information and as a result of that it will limit adoption.

I can see that creating the main resources and letting the tf.json file fill in the property values should allow for the creation of the resources. However, there seems to be an issue with the suffix .html that prevents various resources from being deployed. (Using TF 0.11)

Error asking for user input: Error parsing address 'aws_api_gateway_resource.CustomKey-index.html': Unexpected value for InstanceType field: "html"

[Bug] Plugin picks up sourcemaps as pages

Issue

Expected Behavior

The plugin only looks for .next/serverless/pages/*.js files.

Actual Behavior

The plugin picks up every file in .next/serverless/pages, including *.js.map files.

Steps to Reproduce the Problem

Simply running a build with the latest version of next should suffice.
I do have a few custom settings in my webpack config but none of them have to do with sourcemapping, which as far as I know is enabled by default in nextjs.

Specifications

  • Version: 3.0.0
  • Platform: Darwin
  • Subsystem: n/a

[Feat] Make routes not mandatory

Is your feature request related to a problem? Please describe.
At the moment routes is mandatory. It's not always mandatory for some websites as they could use file names as routing

Describe the solution you'd like
Using the file names of nextjs pages as routes

[Feat] Having more providers

At the moment this plugin supports only AWS as provider.

It might be nice to have different providers (Azure, Google, etc.)

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.