Skip to content

Commit

Permalink
Merge pull request #1 from ernitingarg/main
Browse files Browse the repository at this point in the history
Release to Production 2023-10-20 23:02
  • Loading branch information
ernitingarg authored Oct 20, 2023
2 parents 80891d6 + 7daf30e commit 358a158
Show file tree
Hide file tree
Showing 68 changed files with 2,040 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .github/pr-template/main
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Release to Production {{ .Year }}-{{ .Month }}-{{ .Date }} {{ .Hour }}:{{ .Minute }}
# Pull Requests
{{ range $i, $pull := .Pulls }}
* {{ $pull.Title }} (#{{ $pull.Number }}) @{{ $pull.User.Login }}
{{- end }}
26 changes: 26 additions & 0 deletions .github/workflows/create-pr-to-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Generate Release Pull Request to production

on:
push:
branches:
- main

permissions:
contents: write
pull-requests: write

jobs:
gh-release-pr-generator:
name: gh-release-pr-generator
runs-on: ubuntu-20.04
env:
TZ: Asia/Tokyo
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: ^1.17.1
- name: Install gh-release-pr-generator
run: go install github.com/nekonenene/gh-release-pr-generator@latest
- name: Run gh-release-pr-generator
run: gh-release-pr-generator --token ${{ secrets.GITHUB_TOKEN }} --repo-owner ${{ github.repository_owner }} --repo-name ${{ github.event.repository.name }} --dev-branch main --prod-branch production -template-path .github/pr-template/main
84 changes: 84 additions & 0 deletions .github/workflows/terraform_production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Terraform Apply For Production

on:
push:
branches:
- production
pull_request:
branches:
- production
- main

permissions:
contents: write
pull-requests: write

jobs:
terraform:
runs-on: ubuntu-latest
if: >
!(github.event_name == 'pull_request'
&& github.base_ref != 'production')
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
defaults:
run:
working-directory: projects/my-project/production

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Terraform
uses: hashicorp/setup-terraform@v1

- name: Setup Infracost
uses: infracost/actions/setup@v2
with:
api-key: ${{ env.INFRACOST_API_KEY }}

- name: Extract AWS Region from backend.conf
id: extract-region
run: |
region=$(grep -oP 'region\s*=\s*"\K[^"]+' backend.conf)
echo "AWS_REGION=$region" >> $GITHUB_ENV
- name: Configure AWS CLI
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Terraform Init
run: terraform init -backend-config="backend.conf"

- name: Terraform Validate
run: terraform validate -no-color

- name: Terraform Plan
run: terraform plan -out tfplan.binary -no-color

- name: Terraform show
run: terraform show -json tfplan.binary > plan.json -no-color

- name: Generate Infracost
run: |
infracost breakdown --path plan.json \
--format json \
--out-file /tmp/infracost.json
- name: Post Infracost comment
if: github.event_name == 'pull_request'
run: |
infracost comment github --path /tmp/infracost.json \
--repo $GITHUB_REPOSITORY \
--github-token ${{github.token}} \
--pull-request ${{github.event.pull_request.number}} \
--behavior update
- name: Terraform Apply on Push to production
if: github.event_name == 'push'
run: terraform apply -auto-approve -no-color
80 changes: 80 additions & 0 deletions .github/workflows/terraform_staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Terraform Apply For staging

on:
push:
branches:
- main
pull_request:
branches:
- main

permissions:
contents: write
pull-requests: write

jobs:
terraform:
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
defaults:
run:
working-directory: projects/my-project/staging

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Terraform
uses: hashicorp/setup-terraform@v1

- name: Setup Infracost
uses: infracost/actions/setup@v2
with:
api-key: ${{ env.INFRACOST_API_KEY }}

- name: Extract AWS Region from backend.conf
id: extract-region
run: |
region=$(grep -oP 'region\s*=\s*"\K[^"]+' backend.conf)
echo "AWS_REGION=$region" >> $GITHUB_ENV
- name: Configure AWS CLI
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Terraform Init
run: terraform init -backend-config="backend.conf"

- name: Terraform Validate
run: terraform validate -no-color

- name: Terraform Plan
run: terraform plan -out tfplan.binary -no-color

- name: Terraform show
run: terraform show -json tfplan.binary > plan.json -no-color

- name: Generate Infracost
run: |
infracost breakdown --path plan.json \
--format json \
--out-file /tmp/infracost.json
- name: Post Infracost comment
if: github.event_name == 'pull_request'
run: |
infracost comment github --path /tmp/infracost.json \
--repo $GITHUB_REPOSITORY \
--github-token ${{github.token}} \
--pull-request ${{github.event.pull_request.number}} \
--behavior update
- name: Terraform Apply on Push to main
if: github.event_name == 'push'
run: terraform apply -auto-approve -no-color
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Local .terraform directories
**/.terraform/

# .tfstate files
*.tfstate
*.tfstate.*

# .tfplan files
*.tfplan

# Crash log files
crash.log

# .tfvars files that are meant to be customized
*.auto.tfvars
*.auto.tfvars.json

# Local .git directories
**/.git/

# Lock file
.terraform.lock.*
74 changes: 72 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,72 @@
# infra-terraform-aws
Terraform code to setup AWS infra
# Terraform AWS infra

## Architecture Design

![design](design.png)

## Setup

- To download `terraform`, please follow steps mentioned [here](https://spacelift.io/blog/how-to-install-terraform). Make sure you set the environment variable(s).
- Verify if `terraform` has been installed and configure by executing `terraform -v`.
- Install `AWS CLI` from [here](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).
- Verify if `AWS CLI` has been installed and configued by executing `aws --version`.
- Log in to `AWS Web Console`
- If user exists, then go to `IAM` -> `Users` -> `<user>` -> `Security Credential` -> `Access keys` -> `Create access key` and note down `Access Key ID` and `Secret Access Key`.
- If user doesn't exist then create a user with `programmatic access` to AWS and note down `Access Key ID` and `Secret Access Key`.
- Next step is to configure these credentials in the `AWS CLI` by executing `aws configure`. Enter `Access Key ID` and `Secret Access Key`, keep everything else default.

## Usages

- Go to `projects\my-project\staging` directory.
- Execute `terraform init -backend-config="backend.conf"` command to prepare working directory.
- Execute `terraform plan` to show changes which are required to be performed.
- Execute `terraform apply` to create or update infrastructure.
- Please check other below mentioned commands to be executed:

```
Usage: terraform [global options] <subcommand> [args]
The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.
Main commands:
init Prepare your working directory for other commands
validate Check whether the configuration is valid
plan Show changes required by the current configuration
apply Create or update infrastructure
destroy Destroy previously-created infrastructure
All other commands:
console Try Terraform expressions at an interactive command prompt
fmt Reformat your configuration in the standard style
force-unlock Release a stuck lock on the current workspace
get Install or upgrade remote Terraform modules
graph Generate a Graphviz graph of the steps in an operation
import Associate existing infrastructure with a Terraform resource
login Obtain and save credentials for a remote host
logout Remove locally-stored credentials for a remote host
metadata Metadata related commands
output Show output values from your root module
providers Show the providers required for this configuration
refresh Update the state to match remote systems
show Show the current state or a saved plan
state Advanced state management
taint Mark a resource instance as not fully functional
untaint Remove the 'tainted' state from a resource instance
version Show the current Terraform version
workspace Workspace management
Global options (use these before the subcommand, if any):
-chdir=DIR Switch to a different working directory before executing the
given subcommand.
-help Show this help output, or the help for a specified subcommand.
-version An alias for the "version" subcommand.
```

## Infracost

- To download `infracost`, please follow the instructions mentioned [here](https://www.infracost.io/docs/).
- Go to `projects\my-project\staging` directory.
- Execute `infracost breakdown --path .` to see the cost.
- Please refer official document for more detailed commands.
Binary file added design.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 94 additions & 0 deletions modules/aws/alb/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
locals {
tags = {
Environment = var.env
ProjectName = var.project_name
}

name = "${var.project_name}-${var.env}-${var.lb_name}"
lb_name = local.name
lb_target_group_name = local.name
lb_http_listener_name = "${local.lb_name}-lb-listener-http"
lb_https_listener_name = "${local.lb_name}-lb-listener-https"
lb_security_group_name = "${local.name}-sg-lb"
}

module "sg_lg" {
source = "../network/sg/external"
env = var.env
project_name = var.project_name
sg_name = local.lb_security_group_name
vpc_id = var.vpc_id
}

resource "aws_lb" "lb" {
name = local.lb_name
internal = false
load_balancer_type = "application"
security_groups = [module.sg_lg.sg_id]
subnets = var.vpc_subnet_public_ids
ip_address_type = "ipv4" # fargate managed ec2
enable_cross_zone_load_balancing = true

tags = merge(local.tags, {
Name = "${local.lb_name}-lb"
})
}

resource "aws_lb_target_group" "lb_target_group" {
name = local.lb_target_group_name
port = var.lb_target_group_port
protocol = "HTTP"
vpc_id = var.vpc_id
target_type = "ip"

health_check {
enabled = true
healthy_threshold = "3"
unhealthy_threshold = "2"
interval = "30"
matcher = "200,301"
timeout = "5"
path = coalesce(var.lb_target_group_healthcheck_path, "/")
port = "traffic-port"
}

tags = merge(local.tags, {
Name = "${local.lb_target_group_name}-lb-target-group"
})
}

resource "aws_lb_listener" "lb_listener_http" {
load_balancer_arn = aws_lb.lb.arn
port = 80
protocol = "HTTP"

default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}

tags = merge(local.tags, {
Name = local.lb_http_listener_name
})
}

resource "aws_lb_listener" "lb_listener_https" {
load_balancer_arn = aws_lb.lb.id
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = var.acm_certificate_arn

default_action {
target_group_arn = aws_lb_target_group.lb_target_group.arn
type = "forward"
}

tags = merge(local.tags, {
Name = local.lb_https_listener_name
})
}
Loading

0 comments on commit 358a158

Please sign in to comment.