11 Commits

Author SHA1 Message Date
sid palas
dead4bda7d turn off terraform wrapper 2021-07-05 19:17:11 -07:00
sid palas
521ce1be1e Specify test path 2021-07-05 19:11:03 -07:00
sid palas
4fd6d96faf add go setup step and execute terratest 2021-07-05 19:01:59 -07:00
sid palas
8e07a9ca52 add comment about route53 zone 2021-07-05 16:43:07 -07:00
sid palas
470941a03d add workflow step to run terratest test 2021-07-05 16:35:48 -07:00
sid palas
a35c1c0632 Fix relative source path for web_app module 2021-07-05 15:45:19 -07:00
sid palas
becbd33b93 Disable github action push event trigger 2021-06-27 22:09:11 -07:00
sid palas
3c0fe8a7f4 Update readmes for modules 1-3 2021-06-27 22:07:31 -07:00
sid palas
f21f709b51 Updates during testing of TF 1.0.1 2021-06-27 13:41:03 -07:00
sid palas
4afa2070b3 [docs] Add top level readme 2021-05-27 20:08:59 -07:00
sid palas
d551e98de5 [bugfix] update condition to use event_name==release 2021-05-27 17:39:54 -07:00
14 changed files with 157 additions and 111 deletions

View File

@@ -1,9 +1,10 @@
name: "Terraform"
on:
push:
branches:
- main
# Uncomment to enable staging deployment
# push:
# branches:
# - main
release:
types: [published]
pull_request:
@@ -25,7 +26,8 @@ jobs:
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 0.15.4
terraform_version: 1.0.1
terraform_wrapper: false
- name: Terraform Format
id: fmt
@@ -38,6 +40,7 @@ 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
@@ -72,6 +75,16 @@ 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: |
@@ -81,7 +94,7 @@ jobs:
fi
- name: Terraform Apply Global
if: github.event_name == 'push'
if: github.event_name == 'push' || github.event_name == 'release'
working-directory: 07-managing-multiple-environments/file-structure/global
run: |
terraform init
@@ -92,7 +105,7 @@ jobs:
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 == 'push'
if: steps.check-tag.outputs.environment == 'production' && github.event_name == 'release'
working-directory: 07-managing-multiple-environments/file-structure/production
run: |
terraform init

View File

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

View File

@@ -1,8 +0,0 @@
## 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)

22
02-overview/README.md Normal file
View File

@@ -0,0 +1,22 @@
## 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,4 +1,45 @@
1) Create account credentials
## 03 - Basics
## 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

@@ -1,31 +0,0 @@
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,47 +0,0 @@
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

@@ -1,7 +1,11 @@
terraform {
# THIS BACKEND CONFIG GETS UNCOMMENTED IN IMPORT-BOOTSTRAP
#############################################################
## 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
#############################################################
# backend "s3" {
# bucket = "devops-directive-tf-state"
# bucket = "devops-directive-tf-state" # REPLACE WITH YOUR BUCKET NAME
# key = "03-basics/import-bootstrap/terraform.tfstate"
# region = "us-east-1"
# dynamodb_table = "terraform-state-locking"
@@ -21,7 +25,7 @@ provider "aws" {
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "devops-directive-tf-state"
bucket = "devops-directive-tf-state" # REPLACE WITH YOUR BUCKET NAME
force_destroy = true
versioning {
enabled = true

View File

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

View File

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

View File

@@ -0,0 +1,6 @@
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 := 5 * time.Second
timeBetweenRetries := 10 * time.Second
http_helper.HttpGetWithRetryWithCustomValidation(
t, instanceURL, &tlsConfig, maxRetries, timeBetweenRetries, validate,

45
README.md Normal file
View File

@@ -0,0 +1,45 @@
# 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.