10 Commits

Author SHA1 Message Date
sid palas
771b8b16da remove extra echo step 2021-05-27 15:53:12 -07:00
sid palas
fd8eae8c36 echo check-tag output 2021-05-27 15:52:06 -07:00
sid palas
16ea290cee add echo to check-tag 2021-05-27 15:48:43 -07:00
sid palas
eabb75da33 add check tag step 2021-05-27 15:45:06 -07:00
sid palas
6bb2c4920e wrap condition in braces 2021-05-27 15:41:38 -07:00
sid palas
634ba2582a perform ref check in apply step 2021-05-27 15:40:23 -07:00
sid palas
fe309c5f70 add staging/production split 2021-05-27 15:34:00 -07:00
sid palas
364f66b53e move dns zone to global dir 2021-05-27 15:18:02 -07:00
sid palas
467323fee8 add db_pass secret 2021-05-27 14:54:00 -07:00
sid palas
8b76c065e9 add tf apply step 2021-05-27 14:49:45 -07:00
14 changed files with 117 additions and 171 deletions

View File

@@ -1,12 +1,11 @@
name: "Terraform"
on:
# Uncomment to enable staging deployment
# push:
# branches:
# - main
release:
types: [published]
push:
branches:
- main
tags:
- v\d+\.\d+\.\d+$
pull_request:
jobs:
@@ -26,8 +25,7 @@ jobs:
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 1.0.1
terraform_wrapper: false
terraform_version: 0.15.4
- name: Terraform Format
id: fmt
@@ -40,7 +38,6 @@ jobs:
- name: Terraform Plan
id: plan
if: github.event_name == 'pull_request'
# Route 53 zone must already exist for this to succeed!
run: terraform plan -var db_pass=${{secrets.DB_PASS }} -no-color
continue-on-error: true
@@ -75,38 +72,20 @@ jobs:
if: steps.plan.outcome == 'failure'
run: exit 1
- uses: actions/setup-go@v2
with:
go-version: '^1.15.5'
- name : Terratest Execution
if: github.event_name == 'pull_request'
working-directory: 08-testing/tests/terratest
run: |
go test . -v timeout 10m
- name: Check tag
id: check-tag
run: |
if [[ ${{ github.ref }} =~ ^refs\/tags\/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo ::set-output name=environment::production
elif [[ ${{ github.ref }} == 'refs/heads/main' ]]; then echo ::set-output name=environment::staging
if [[ ${{ github.ref }} =~ ^refs/tags/vd+\.d+\.d+$ ]]; then echo ::set-output name=environment::production
elif [[ github.ref == 'refs/heads/main' ]]; then echo ::set-output name=environment::staging
else echo ::set-output name=environment::unknown
fi
- name: Terraform Apply Global
if: github.event_name == 'push' || github.event_name == 'release'
working-directory: 07-managing-multiple-environments/file-structure/global
run: |
terraform init
terraform apply -auto-approve
- name: Terraform Apply Staging
if: steps.check-tag.outputs.environment == 'staging' && github.event_name == 'push'
if: steps.check-tag.outputs.environment == 'production' && github.event_name == 'push'
working-directory: 07-managing-multiple-environments/file-structure/staging
run: terraform apply -var db_pass=${{secrets.DB_PASS }} -auto-approve
- name: Terraform Apply Production
if: steps.check-tag.outputs.environment == 'production' && github.event_name == 'release'
if: steps.check-tag.outputs.environment == 'staging' && github.event_name == 'push'
working-directory: 07-managing-multiple-environments/file-structure/production
run: |
terraform init
terraform apply -var db_pass=${{secrets.DB_PASS }} -auto-approve
run: terraform apply -var db_pass=${{secrets.DB_PASS }} -auto-approve

View File

@@ -1,3 +0,0 @@
# 01 - Evolution of Cloud + Infrastructure as Code
This module doesn't have any corresponding code.

View File

@@ -0,0 +1,8 @@
## Install Terraform
1) install terraform
## AWS Account Setup
2) create non-root AWS user
3) Add AmazonEC2FullAccess
4) Save Access key + secret key (or use AWS CLI `aws configure` -- https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)

View File

@@ -1,22 +0,0 @@
## 02 - Overview + Setup
## Install Terraform
Official installation instructions from HashiCorp: https://learn.hashicorp.com/tutorials/terraform/install-cli
## AWS Account Setup
AWS Terraform provider documentation: https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication
1) create non-root AWS user
2) Add the necessary IAM roles (e.g. AmazonEC2FullAccess)
3) Save Access key + secret key (or use AWS CLI `aws configure` -- https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)
## Hello World
`./main.tf` contains minimal configuration to provision an EC2 instance.
1) `aws configure`
2) `terraform init`
3) `terraform plan`
4) `terraform apply`

View File

@@ -1,45 +1,4 @@
## 03 - Basics
1) Create account credentials
## Remote Backends
Remote backends enable storage of TF state in a remote, location to enable secure collaboration.
### Terraform Cloud
https://www.terraform.io/cloud
`./terraform-cloud-backend/main.tf`
### AWS S3 + Dynamo DB
Steps to initialize backend in AWS and manage it with Terraform:
1) Use config from `./aws-backend/` (init, plan, apply) to provision s3 bucket and dynamoDB table with local state
2) Uncomment the remote backend configuration
3) Reinitialize with `terraform init`:
```
Do you want to copy existing state to the new backend?
Pre-existing state was found while migrating the previous "local" backend to the
newly configured "s3" backend. No existing state was found in the newly
configured "s3" backend. Do you want to copy this state to the new "s3"
backend? Enter "yes" to copy and "no" to start with an empty state.
Enter a value: yes
```
Now the S3 bucket and dynamoDB table are mam and are able to be used as the state backend!
## Web-App
Generic web application architecture including:
- EC2 instances
- S3 bucket
- RDS instance
- Load balancer
- Route 53 DNS config
This example will be refined and improved in later modules.
## Architecture
![](./web-app/architecture.png)

View File

@@ -0,0 +1,31 @@
Steps to initialize backend in AWS and manage it with Terraform:
1) Use config from `bootstrap` (init, plan, apply) to provision s3 bucket and dynamoDB table with local state
2) copy state file into import-bootstrap
1) cp terraform.tfstate ../import-bootstrap
3) Initialize within `import-bootstrap` using `terraform init`
4) Uncomment out s3 backend provider:
```
backend "s3" {
bucket = "devops-directive-tf-state"
key = "tf-infra/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locking"
encrypt = true
}
```
4) Reinitialize with `terraform init`:
```
Do you want to copy existing state to the new backend?
Pre-existing state was found while migrating the previous "local" backend to the
newly configured "s3" backend. No existing state was found in the newly
configured "s3" backend. Do you want to copy this state to the new "s3"
backend? Enter "yes" to copy and "no" to start with an empty state.
Enter a value: yes
```
Now the S3 bucket and dynamoDB table are managed by Terraform and are able to be used as the state backend!

View File

@@ -1,11 +1,7 @@
terraform {
#############################################################
## AFTER RUNNING TERRAFORM APPLY (WITH LOCAL BACKEND)
## YOU WILL UNCOMMENT THIS CODE THEN RERUN TERRAFORM INIT
## TO SWITCH FROM LOCAL BACKEND TO REMOTE AWS BACKEND
#############################################################
# THIS BACKEND CONFIG GETS UNCOMMENTED IN IMPORT-BOOTSTRAP
# backend "s3" {
# bucket = "devops-directive-tf-state" # REPLACE WITH YOUR BUCKET NAME
# bucket = "devops-directive-tf-state"
# key = "03-basics/import-bootstrap/terraform.tfstate"
# region = "us-east-1"
# dynamodb_table = "terraform-state-locking"
@@ -25,7 +21,7 @@ provider "aws" {
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "devops-directive-tf-state" # REPLACE WITH YOUR BUCKET NAME
bucket = "devops-directive-tf-state"
force_destroy = true
versioning {
enabled = true

View File

@@ -0,0 +1,47 @@
terraform {
### UNCOMMENT THIS AFTER INITIALIZNG ###
# backend "s3" {
# bucket = "devops-directive-tf-state"
# key = "03-basics/import-bootstrap/terraform.tfstate"
# region = "us-east-1"
# dynamodb_table = "terraform-state-locking"
# encrypt = true
# }
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "devops-directive-tf-state"
force_destroy = true
versioning {
enabled = true
}
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
}
resource "aws_dynamodb_table" "terraform_locks" {
name = "terraform-state-locking"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}

View File

@@ -0,0 +1,8 @@
## Terraform Cloud Account Setup
1) Create account at terraform.io
2) Use terraform login
3) Set any necessary credentials for whichever cloud services you are using because with terraform cloud backend, the plan/apply are actually run remotely.
```
# AWS_ACCESS_KEY_ID
# AWS_SECRET_ACCESS_KEY
```

View File

@@ -21,14 +21,8 @@ provider "aws" {
region = "us-east-1"
}
variable "db_pass_1" {
description = "password for database #2"
type = string
sensitive = true
}
variable "db_pass_2" {
description = "password for database #2"
variable "db_pass" {
description = "password for database"
type = string
sensitive = true
}
@@ -45,7 +39,7 @@ module "web_app_1" {
create_dns_zone = true
db_name = "webapp1db"
db_user = "foo"
db_pass = var.db_pass_1
db_pass = var.db_pass
}
module "web_app_2" {
@@ -59,6 +53,6 @@ module "web_app_2" {
instance_type = "t2.small"
create_dns_zone = true
db_name = "webapp2db"
db_user = "bar"
db_pass = var.db_pass_2
db_user = "foo"
db_pass = var.db_pass
}

View File

@@ -32,7 +32,7 @@ locals {
}
module "web_app" {
source = "../../06-organization-and-modules/web-app-module"
source = "../../05-organization-and-modules/web-app-module"
# Input Variables
bucket_name = "devops-directive-web-app-data-${local.environment_name}"

View File

@@ -1,6 +0,0 @@
How to run this test?
Build, then run...
`go test -v timeout 10m`

View File

@@ -23,7 +23,7 @@ func TestTerraformHelloWorldExample(t *testing.T) {
instanceURL := terraform.Output(t, terraformOptions, "url")
tlsConfig := tls.Config{}
maxRetries := 30
timeBetweenRetries := 10 * time.Second
timeBetweenRetries := 5 * time.Second
http_helper.HttpGetWithRetryWithCustomValidation(
t, instanceURL, &tlsConfig, maxRetries, timeBetweenRetries, validate,

View File

@@ -1,45 +0,0 @@
# DevOps Directive Terraform Course
This is the companion repo to the complete Terraform course from DevOps Directive (https://www.youtube.com/c/DevOpsDirective)
*Note:* The videos for the course have not been released yet... stay tuned!
## 01 - Evolution of Cloud + Infrastructure as Code
High level overview of the evolution of cloud computing and infrastructure as code.
This module does not have any corresponding code.
## 02 - Overview + Setup
Terraform overview and setup instructions.
Includes basic `hello world` terraform config to provision a single AWS EC2 instance.
## 03 - Basics
Covers main usage pattern, setting up remote backends (where the terraform state is stored) using terraform Cloud and AWS, and provides a naive implementation of a web application architecture.
## 04 - Variables and Outputs
Introduces the concepts of variables which enable Terraform configurations to be flexible and composable. Refactors web application to use these features.
## 05 - Language Features
Describes additional features of the Hashicorp Configuration Language (HCL).
## 06 - Organization and Modules
Demonstrates how to structure terraform code into reuseable modules and how to instantiate/configure modules.
## 07 - Managing Multiple Environments
Shows two methods for managing multiple environments (e.g. dev/staging/prodution) with Terraform.
## 08 - Testing
Explains different types of testing (manual + automated) for Terraform modules and configurations.
## 09 - Developer Workflows + CI/CD
Covers how teams can work together with Terraform and how to set up CI/CD pipelines to keep infrastructure environments up to date.