From 4fa8bb48c57658c8d0c54bc764d1c3364cef7e77 Mon Sep 17 00:00:00 2001 From: Joseph Arrieta Date: Wed, 18 Oct 2017 16:10:18 -0500 Subject: [PATCH] this is a module for being used when we are using AWS accounts that are under EC2-classic way and don't use a VPC by default added a readme explanation of why this module exist and its purpose --- modules/ec2-classic/ami.tf | 7 ++ modules/ec2-classic/ec2.tf | 85 +++++++++++++++++++ modules/ec2-classic/key_pair.tf | 4 + modules/ec2-classic/main.tf | 22 +++++ modules/ec2-classic/provision/app/index.js | 8 ++ .../ec2-classic/provision/app/package.json | 14 +++ .../provision/install_dummy_app.sh | 14 +++ .../ec2-classic/provision/install_nginx.sh | 9 ++ modules/ec2-classic/provision/install_nvm.sh | 20 +++++ .../ec2-classic/provision/install_postgres.sh | 21 +++++ .../install_ubuntu_build_essential.sh | 7 ++ modules/ec2-classic/provision/nginx_app.conf | 18 ++++ modules/ec2-classic/provision/pm2.json | 10 +++ modules/ec2-classic/security_group.tf | 39 +++++++++ readme.md | 40 ++++++++- 15 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 modules/ec2-classic/ami.tf create mode 100644 modules/ec2-classic/ec2.tf create mode 100644 modules/ec2-classic/key_pair.tf create mode 100644 modules/ec2-classic/main.tf create mode 100644 modules/ec2-classic/provision/app/index.js create mode 100644 modules/ec2-classic/provision/app/package.json create mode 100644 modules/ec2-classic/provision/install_dummy_app.sh create mode 100644 modules/ec2-classic/provision/install_nginx.sh create mode 100644 modules/ec2-classic/provision/install_nvm.sh create mode 100644 modules/ec2-classic/provision/install_postgres.sh create mode 100644 modules/ec2-classic/provision/install_ubuntu_build_essential.sh create mode 100644 modules/ec2-classic/provision/nginx_app.conf create mode 100644 modules/ec2-classic/provision/pm2.json create mode 100644 modules/ec2-classic/security_group.tf diff --git a/modules/ec2-classic/ami.tf b/modules/ec2-classic/ami.tf new file mode 100644 index 0000000..f26bdda --- /dev/null +++ b/modules/ec2-classic/ami.tf @@ -0,0 +1,7 @@ +data "aws_ami" "ubuntu" { + most_recent = true + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20170721"] + } +} \ No newline at end of file diff --git a/modules/ec2-classic/ec2.tf b/modules/ec2-classic/ec2.tf new file mode 100644 index 0000000..abaf98c --- /dev/null +++ b/modules/ec2-classic/ec2.tf @@ -0,0 +1,85 @@ +resource "aws_instance" "nginx_node" { + ami = "${data.aws_ami.ubuntu.id}" + instance_type = "${var.instance_type}" + associate_public_ip_address = true + subnet_id = "${aws_subnet.us-east-1a-public.id}" + + key_name = "${aws_key_pair.deployer-key.key_name}" + security_groups = ["${aws_security_group.node_nginx.id}"] // node-nginx + + tags { + Name = "${var.project_name} [demo]" + Description = "Created with aws-provisioner for ${var.project_name}" + } + + provisioner "remote-exec" { + inline = [ + "mkdir -p ~/provision" + ] + } + + provisioner "file" { + source = "${path.module}/provision/" + destination = "/home/ubuntu/provision/" + } + + provisioner "remote-exec" { + inline = [ + "chmod +x /home/ubuntu/provision/*", + "/home/ubuntu/provision/install_ubuntu_build_essential.sh", + "/home/ubuntu/provision/install_nvm.sh", + "/home/ubuntu/provision/install_dummy_app.sh", + "/home/ubuntu/provision/install_nginx.sh", + ] + } + + connection { + user = "ubuntu" + type = "ssh" + private_key = "${file("${var.private_key_path}")}" + } +} + +resource "aws_vpc" "selected" { + cidr_block = "10.0.0.0/16" + enable_dns_hostnames = true + enable_dns_support = true + tags { + Name = "${var.project_name}" + } +} + +resource "aws_subnet" "us-east-1a-public" { + vpc_id = "${aws_vpc.selected.id}" + cidr_block = "10.0.1.0/25" + availability_zone = "us-east-1a" +} + +resource "aws_internet_gateway" "main" { + vpc_id = "${aws_vpc.selected.id}" + tags { + Name = "${var.project_name}" + } +} + +resource "aws_default_route_table" "r" { + default_route_table_id = "${aws_vpc.selected.default_route_table_id}" + + route { + cidr_block = "0.0.0.0/0" + gateway_id = "${aws_internet_gateway.main.id}" + } + + tags { + Name = "${var.project_name}" + } + +} + +output "nginx_node.public_dns" { + value = "${aws_instance.nginx_node.public_dns}" +} + +output "nginx_node.public_ip" { + value = "${aws_instance.nginx_node.public_ip}" +} diff --git a/modules/ec2-classic/key_pair.tf b/modules/ec2-classic/key_pair.tf new file mode 100644 index 0000000..c8dc9ab --- /dev/null +++ b/modules/ec2-classic/key_pair.tf @@ -0,0 +1,4 @@ +resource "aws_key_pair" "deployer-key" { + key_name = "${var.project_id}-key" + public_key = "${var.public_key}" +} \ No newline at end of file diff --git a/modules/ec2-classic/main.tf b/modules/ec2-classic/main.tf new file mode 100644 index 0000000..9fbf6ba --- /dev/null +++ b/modules/ec2-classic/main.tf @@ -0,0 +1,22 @@ +provider "aws" { + region = "${var.region}" + profile = "${var.profile}" +} + +variable "region" {} +variable "profile" {} + +variable "project_name" { + default = "Hello World" +} + +variable "project_id" { + default = "hello-world" +} + +variable "instance_type" { + default = "t2.micro" +} + +variable "private_key_path" {} +variable "public_key" {} diff --git a/modules/ec2-classic/provision/app/index.js b/modules/ec2-classic/provision/app/index.js new file mode 100644 index 0000000..0408bec --- /dev/null +++ b/modules/ec2-classic/provision/app/index.js @@ -0,0 +1,8 @@ +const express = require('express'); + +const app = express(); + +app.get('/', (req, res) => { + res.send(`

Dummy app

Response from PID: ${process.pid}. Hit F5 many times!

`); +}); +app.listen(3000, () => console.log('Listening on port 3000!')); diff --git a/modules/ec2-classic/provision/app/package.json b/modules/ec2-classic/provision/app/package.json new file mode 100644 index 0000000..40905aa --- /dev/null +++ b/modules/ec2-classic/provision/app/package.json @@ -0,0 +1,14 @@ +{ + "name": "sample-app", + "version": "0.0.1", + "main": "index.js", + "author": { + "name": "Julian Reyes", + "email": "jreyes@bixlabs.com", + "url": "https://twitter.com/rokemaster" + }, + "dependencies": { + "express": "^4.15.4" + }, + "private": true +} diff --git a/modules/ec2-classic/provision/install_dummy_app.sh b/modules/ec2-classic/provision/install_dummy_app.sh new file mode 100644 index 0000000..1443d01 --- /dev/null +++ b/modules/ec2-classic/provision/install_dummy_app.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# This loads nvm +export NVM_DIR="$HOME/.nvm" +\. "$NVM_DIR/nvm.sh" + +cp -r $HOME/provision/app $HOME/ +cp -r $HOME/provision/pm2.json $HOME/app-pm2.json +npm i -g pm2 + +cd $HOME/app +npm i + +pm2 start $HOME/app-pm2.json \ No newline at end of file diff --git a/modules/ec2-classic/provision/install_nginx.sh b/modules/ec2-classic/provision/install_nginx.sh new file mode 100644 index 0000000..6518d34 --- /dev/null +++ b/modules/ec2-classic/provision/install_nginx.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e +export DEBIAN_FRONTEND=noninteractive + +sudo apt-get install -y nginx +sudo rm /etc/nginx/sites-enabled/default +sudo ln -s $HOME/provision/nginx_app.conf /etc/nginx/sites-enabled/default +sudo systemctl restart nginx \ No newline at end of file diff --git a/modules/ec2-classic/provision/install_nvm.sh b/modules/ec2-classic/provision/install_nvm.sh new file mode 100644 index 0000000..cca1586 --- /dev/null +++ b/modules/ec2-classic/provision/install_nvm.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +function latest_version() { + curl -s https://api.github.com/repos/creationix/nvm/releases/latest \ + | grep 'tag_name' \ + | cut -d '"' -f 4 +} + +function install_version() { + curl "https://raw.githubusercontent.com/creationix/nvm/${1}/install.sh" \ + | bash +} + +install_version `latest_version` + +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm +[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion + +nvm install 8.4.0 \ No newline at end of file diff --git a/modules/ec2-classic/provision/install_postgres.sh b/modules/ec2-classic/provision/install_postgres.sh new file mode 100644 index 0000000..e20ee11 --- /dev/null +++ b/modules/ec2-classic/provision/install_postgres.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +DB_NAME=${1} + +export DEBIAN_FRONTEND=noninteractive + +## Install postgres +sudo add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main" +wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - +sudo apt-get update +sudo apt-get install -y postgresql-9.6 + +## Setup postgres +sudo sed -i.bak -e 's/peer/trust/' /etc/postgresql/9.6/main/pg_hba.conf +sudo systemctl restart postgresql +echo "ALTER USER postgres WITH PASSWORD 'postgres';" | psql -U postgres + +## Setup database +echo "CREATE DATABASE hey_mozo ${DB_NAME};" | psql -U postgres diff --git a/modules/ec2-classic/provision/install_ubuntu_build_essential.sh b/modules/ec2-classic/provision/install_ubuntu_build_essential.sh new file mode 100644 index 0000000..db417b1 --- /dev/null +++ b/modules/ec2-classic/provision/install_ubuntu_build_essential.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -e +export DEBIAN_FRONTEND=noninteractive + +sudo apt-get update +sudo apt-get install -y build-essential libssl-dev diff --git a/modules/ec2-classic/provision/nginx_app.conf b/modules/ec2-classic/provision/nginx_app.conf new file mode 100644 index 0000000..7858c0b --- /dev/null +++ b/modules/ec2-classic/provision/nginx_app.conf @@ -0,0 +1,18 @@ +upstream app { + server 127.0.0.1:3000; +} + +server { + listen 80 default_server; + listen [::]:80 default_server; + + server_name _; + + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_pass http://app; + } +} \ No newline at end of file diff --git a/modules/ec2-classic/provision/pm2.json b/modules/ec2-classic/provision/pm2.json new file mode 100644 index 0000000..0a46fa0 --- /dev/null +++ b/modules/ec2-classic/provision/pm2.json @@ -0,0 +1,10 @@ +{ + "name": "dummy-app", + "cwd": "/home/ubuntu/app", + "script": "index.js", + "env": { + "NODE_ENV": "production" + }, + "instances": 2, + "exec_mode": "cluster" +} \ No newline at end of file diff --git a/modules/ec2-classic/security_group.tf b/modules/ec2-classic/security_group.tf new file mode 100644 index 0000000..7b30c80 --- /dev/null +++ b/modules/ec2-classic/security_group.tf @@ -0,0 +1,39 @@ +resource "aws_security_group" "node_nginx" { + name = "${var.project_id}-node-nginx" + description = "Machine with Nginx and Node" + vpc_id = "${aws_vpc.selected.id}" + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_security_group_rule" "node_nginx_http" { + from_port = 80 + protocol = "tcp" + security_group_id = "${aws_security_group.node_nginx.id}" + to_port = 80 + type = "ingress" + cidr_blocks = ["0.0.0.0/0"] +} + +resource "aws_security_group_rule" "node_nginx_ssh" { + from_port = 22 + protocol = "tcp" + security_group_id = "${aws_security_group.node_nginx.id}" + to_port = 22 + type = "ingress" + cidr_blocks = ["0.0.0.0/0"] +} + +resource "aws_security_group_rule" "node_nginx_https" { + from_port = 443 + protocol = "tcp" + security_group_id = "${aws_security_group.node_nginx.id}" + to_port = 443 + type = "ingress" + cidr_blocks = ["0.0.0.0/0"] +} diff --git a/readme.md b/readme.md index 3c56657..2bf4355 100644 --- a/readme.md +++ b/readme.md @@ -32,7 +32,45 @@ output "my_project.public_dns" { } ``` -then `terraform init`, `terraform get`, `terraform plan` and `terraform apply` and you are good to go. +then `terraform get`, `terraform init`, `terraform plan` and `terraform apply` and you are good to go. + +## `modules/ec2-classic` +You can use this module if your AWS account is a EC2-classic account, check [here](https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/default-vpc.html) + +So what does this module do? In case you want to create everything from scratch in a EC2-Classic AWS account you can use this module. +Here is a list of what this module is doing for you: + + * We create a VPC + * We create a Route Table rule for the VPC in the default Route table of that VPC + * Create an Internet Gateway and associate it with the VPC we just created. + * Create a subnet and associate it with the VPC. + * Associate the Security Group that we are creating with the VPC we just created, all of this is to be able to have "egress" rules in the Security Group. + +### How to use + +> **Note** Before continue you need to [install terraform][1] and also have configured an [aws named profile][2] + +Define your resource, remember some ssh key pair should be create before + +``` +module "my_project" { + source = "github.com/bixlabs/aws-provisioner/modules/ec2" + project_id = "my_project" + project_name = "Awesome project" + region = "us-east-1" + profile = "my_aws_profile" + + private_key_path = "~/.ssh/my-ec2-amazon-pair.pem" + public_key = "ssh-rsa AAAAB3NzaC1yc2E... " +} + +output "my_project.public_dns" { + value = "${module.my_project.nginx_node.public_dns}" +} +``` + +then `terraform get`, `terraform init`, `terraform plan` and `terraform apply` and you are good to go. + ## `modules/ec2-postgresql` it will create a ubuntu 16.04 with all from `modules/ec2` plus