├── 01 - Introduction ├── Key-concepts.md └── ReadME.md ├── 02 - Command basics ├── Commands.md ├── Credentials.md ├── Project1 │ ├── Project1-solution │ │ ├── project1-solution.md │ │ └── vpc.tf │ └── project1.md ├── ReadME.md └── manifests │ └── ec2instance.tf ├── 03 - Language Syntax ├── ReadME.md ├── manifests │ ├── app1-install.sh │ ├── ec2instance.tf │ └── version.tf └── top-level-blocks-sample.md ├── 04 - Settings ├── Project2 │ ├── Project-2.md │ └── Project2 solution │ │ └── Project2-solution.md ├── ReadME.md └── manifests │ ├── app1-install.sh │ ├── ec2instance.tf │ └── providers.tf ├── 05 - Variables and Data Sources ├── ReadME.md ├── manifests │ ├── Terraform-input-variables │ │ ├── 01-Basic-variables │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── 02-Sensitive-input-variables │ │ │ ├── rds-db.tf │ │ │ ├── secrets.tfvars │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── 03-Assign-when-prompted │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── 04-Override-default-with-cli-var │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── 05-Override-with-environmental-variables │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── 06-terraform-tfvars │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── terraform.tfvars │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── 07-tfvars-var-file │ │ │ ├── app.tfvars │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── terraform.tfvars │ │ │ ├── variables.tf │ │ │ ├── versions.tf │ │ │ └── web.tfvars │ │ ├── 08-auto-tfvars │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── terraform.tfvars │ │ │ ├── variables.tf │ │ │ ├── versions.tf │ │ │ └── web.auto.tfvars │ │ ├── 09-input-variable-list │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── 10-input-variable-map │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── variable.tf │ │ │ └── versions.tf │ │ └── File-function │ │ │ ├── apache-install.sh │ │ │ ├── ec2.tf │ │ │ ├── sg.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ ├── example1 │ │ ├── data.tf │ │ ├── ec2.tf │ │ ├── provider.tf │ │ └── variables.tf │ └── example2 │ │ ├── ami-datasource.tf │ │ ├── app1-install.sh │ │ ├── ec2instance.tf │ │ ├── ec2securitygroups.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf ├── variable-files.md └── variable-types.md ├── 06 - Meta Arguments-count, loops, lists, maps ├── Dynamic blocks │ ├── ami-datasource.tf │ ├── ec2.tf │ ├── main.tf │ ├── sg.tf │ └── variables.tf ├── README.md └── manifests │ ├── ami-datasource.tf │ ├── app1-install.sh │ ├── ec2instance.tf │ ├── ec2securitygroups.tf │ ├── outputs.tf │ ├── variables.tf │ └── versions.tf ├── 07 - Modules ├── example1-ec2 │ └── ec2 │ │ ├── ami-datasource.tf │ │ └── ec2.tf ├── example2-db-web-eip-sg │ ├── db │ │ ├── ami-datasource.tf │ │ └── db.tf │ ├── eip │ │ └── eip.tf │ ├── main.tf │ ├── sg │ │ └── sg.tf │ ├── terraform.tfstate │ ├── terraform.tfstate.backup │ └── web │ │ ├── ami-datasource.tf │ │ ├── server-script.sh │ │ └── web.tf ├── example3-vpc │ └── AWS-VPC-using-Terraform │ │ ├── README.md │ │ └── terraform-manifests │ │ ├── vpc-module-standardized │ │ ├── 01-versions.tf │ │ ├── 02-variables.tf │ │ ├── 03-local-values.tf │ │ ├── 04-vpc-variables.tf │ │ ├── 05-vpc-module.tf │ │ ├── 06-vpc-outputs.tf │ │ ├── terraform.tfvars │ │ └── vpc.auto.tfvars │ │ └── vpc-module │ │ ├── variables.tf │ │ ├── versions.tf │ │ └── vpc.tf └── terraform-eks │ └── terraform-eks │ └── README.md ├── 08 - Terraform backend ├── ReadMe.md └── Remote state │ ├── remote-state-data-source │ └── remote-backend │ │ ├── ami-datasource.tf │ │ ├── backend.tf │ │ ├── ec2.tf │ │ └── variables.tf │ └── vpc module │ ├── 01-backend.tf │ ├── 02-generic-variables.tf │ ├── 03-local-values.tf │ ├── 04-vpc-variables.tf │ ├── 05-vpc-module.tf │ ├── 06-vpc-outputs.tf │ ├── terraform.tfvars │ └── vpc.auto.tfvars └── 09 - Remote state data source └── remote-state-data-source ├── 01-backend.tf ├── 02-generic-variables.tf ├── 03-local-values.tf ├── 04-vpc-variables.tf ├── 05-vpc-module.tf ├── 06-vpc-outputs.tf ├── remote-data-source ├── ami-datasource.tf └── remote-ec2.tf ├── terraform.tfvars └── vpc.auto.tfvars /01 - Introduction/Key-concepts.md: -------------------------------------------------------------------------------- 1 | ## **Introduction to Terraform** 2 | 3 | Key Concepts: 4 | a) **Infrastructure as a Code** 5 | - Managing and provisioning of infrastructure through code instead of manually 6 | - Files that contain configurations are created and makes it easy to edit and distribute 7 | - Ensures that the same environment is provisioned everytime. 8 | - Helps avoid undocumented, ad-hoc configuration changes 9 | - Easy to version control 10 | - Can create infrastructure in modular components 11 | - Gives you a template to follow for provisioning 12 | b) **Benefits:** 13 | - Cost reduction 14 | - Increase in speed of deployment 15 | - Reduce errors 16 | - Improve infrastructure consistency 17 | - Eliminate configuration drift 18 | 19 | ##**What is Terraform?:** 20 | - IaaC tool from Hashicorp 21 | - Used for building, changing and managing infrastructure in a safe, repeatable way 22 | - Uses HCL - Hashicorp Configuration Language - human readable 23 | - Reads configuration files and provides an execution plan which can be reviewed before being applied. 24 | - It is platform agnostic - can manage a heterogeneous environment - multi cloud 25 | - State management - creates a state file when a project is first initialized. Uses this state file to create plans and make changes based on the desired and current state of the infrastructure. 26 | - Creates operator confidence 27 | 28 | ##**Terraform Configuration Files** 29 | - Terraform uses declarative syntax to describe your Infrastructure as Code (IaC) infrastructure 30 | and then persist it in configuration files that can be shared, reviewed, edited, versioned, 31 | preserved, and reused. 32 | - Terraform configuration files can use either of two formats: Terraform domain-specific 33 | language (HashiCorpConfiguration Language format [HCL]), which is the recommended 34 | approach, or JSON format if the files need to be machine-readable. 35 | - Configuration files that use the HCL format end with the .tf file extension; 36 | - Those using JSON format end with the .tf.json file extension. 37 | - The Terraform format is human-readable, while the JSON format is machine readable 38 | -------------------------------------------------------------------------------- /01 - Introduction/ReadME.md: -------------------------------------------------------------------------------- 1 | # Terraform & AWS CLI Installation 2 | 3 | ## A) Prerequisites 4 | - Install Terraform CLI 5 | - Install AWS CLI 6 | - Install VS Code Editor - recommended for this course 7 | - Install HashiCorp Terraform plugin for VS Code - recommended 8 | 9 | 10 | ## B) MACOS - Terraform Install 11 | - [Download Terraform MAC](https://www.terraform.io/downloads.html) 12 | - [Install CLI](https://learn.hashicorp.com/tutorials/terraform/install-cli) 13 | - Unzip the package 14 | ``` 15 | # Copy binary zip file to a folder 16 | mkdir /Users//Documents/terraform-install 17 | COPY Package to "terraform-install" folder 18 | 19 | # Unzip 20 | unzip 21 | unzip terraform_1.0.10_darwin_amd64.zip 22 | 23 | # Copy terraform binary to /usr/local/bin 24 | echo $PATH 25 | mv terraform /usr/local/bin 26 | 27 | # Verify Version 28 | terraform version 29 | 30 | # To Uninstall Terraform (NOT REQUIRED) 31 | rm -rf /usr/local/bin/terraform 32 | ``` 33 | 34 | ## C) MACOS - Install VSCode Editor and terraform plugin 35 | - [Microsoft Visual Studio Code Editor](https://code.visualstudio.com/download) 36 | - [Hashicorp Terraform Plugin for VS Code](https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform) 37 | 38 | 39 | ### D) MACOS - Install AWS CLI 40 | - [AWS CLI Install](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 41 | - [Install AWS CLI - MAC](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-mac.html#cliv2-mac-install-cmd) 42 | 43 | ``` 44 | # Install AWS CLI V2 45 | curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg" 46 | sudo installer -pkg AWSCLIV2.pkg -target / 47 | which aws 48 | aws --version 49 | 50 | # Uninstall AWS CLI V2 (NOT REQUIRED) 51 | which aws 52 | ls -l /usr/local/bin/aws 53 | sudo rm /usr/local/bin/aws 54 | sudo rm /usr/local/bin/aws_completer 55 | sudo rm -rf /usr/local/aws-cli 56 | ``` 57 | 58 | 59 | ## E) MACOS - Configure AWS Credentials 60 | - **Pre-requisite:** Should have AWS Account. 61 | - [Create an AWS Account](https://portal.aws.amazon.com/billing/signup?nc2=h_ct&src=header_signup&redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start) 62 | 63 | - **Role**: 64 | -If your terraform server is in the cloud, then create a role and attach the role to your server. 65 | 66 | 67 | - Generate Security Credential s using AWS Management Console 68 | - Go to Services -> IAM -> Users -> "Your-Admin-User" -> Security Credentials -> Create Access Key 69 | - Configure AWS credentials using SSH Terminal on your local desktop 70 | 71 | # **Configure AWS Credentials in command line** 72 | ``` 73 | $ aws configure 74 | AWS Access Key ID [None]: AKIASUF7DEFKSIAWMZ7K 75 | AWS Secret Access Key [None]: WL9G9Tl8lGm7w9t7B3NEDny1+w3N/K5F3HWtdFH/ 76 | Default region name [None]: us-west-2 77 | Default output format [None]: json 78 | 79 | # Verify if we are able list S3 buckets 80 | aws s3 ls 81 | ``` 82 | - Verify the AWS Credentials Profile 83 | ``` 84 | cat $HOME/.aws/credentials 85 | ``` 86 | #**Command to reset your AWS credentials incase of a credentials error**: 87 | 88 | $ for var in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_SECURITY_TOKEN ; do eval unset $var ; done 89 | 90 | ## F) Windows OS - Terraform & AWS CLI Install 91 | - [Download Terraform](https://www.terraform.io/downloads.html) 92 | - [Install CLI](https://learn.hashicorp.com/tutorials/terraform/install-cli) 93 | - Unzip the package 94 | - Create new folder `binaries` 95 | - Copy the `terraform.exe` to a `binaries` 96 | - Set PATH in windows 97 | **How to set the windows path: Windows 8/10** 98 | In Search, search for and then select: 99 | System (Control Panel) 100 | Click the Advanced system settings link. 101 | Click Environment Variables. 102 | In the section System Variables find the PATH environment variable and select it. 103 | Click Edit. If the PATH environment variable does not exist, click New. 104 | In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. 105 | Click OK. Close all remaining windows by clicking OK. 106 | 107 | - Install [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 108 | 109 | ## Terraform install on windows using a packet manager 110 | -Install terraform on windows using the windows package manager(Use powershell and install as administrator). 111 | **$ choco install terraform** 112 | 113 | ## G) Linux OS - Terraform & AWS CLI Install 114 | - [Download Terraform](https://www.terraform.io/downloads.html) 115 | - [Linux OS - Terraform Install](https://learn.hashicorp.com/tutorials/terraform/install-cli) 116 | 117 | # Install Terraform on Ubuntu: 118 | $sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl 119 | $curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - 120 | $sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" 121 | $sudo apt-get update && sudo apt-get install terraform 122 | 123 | # Install Terraform on RHEL: 124 | **Install aws cli** 125 | sudo yum update -y 126 | sudo yum install curl unzip wget -y 127 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 128 | unzip awscliv2.zip 129 | sudo ./aws/install 130 | 131 | **Install Terraform** 132 | a) *Download binary* 133 | sudo yum update -y 134 | sudo yum install wget unzip -y 135 | sudo wget https://releases.hashicorp.com/terraform/1.4.4/terraform_1.1.4_linux_amd64.zip 136 | sudo unzip terraform_1.1.4_linux_amd64.zip -d /usr/local/bin 137 | terraform -v 138 | 139 | b) *Install from hashicorp repo* 140 | sudo yum install -y yum-utils 141 | sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo 142 | sudo yum -y install terraform 143 | -------------------------------------------------------------------------------- /02 - Command basics/Commands.md: -------------------------------------------------------------------------------- 1 | ## **Terraform basic commands** 2 | 3 | #**terraform init** 4 | • initializes a working directory containing Terraform configuration files. 5 | • performs 6 | - backend initialization 7 | - storage for terraform state file. 8 | - modules installation, 9 | - downloaded from terraform registry to local path 10 | - provider(s) plugins installation, 11 | - the plugins are downloaded in the sub-directory of the present working directory at the path of .terraform/plugins 12 | • supports -upgrade to update all previously installed plugins to the newest version that complies with the configuration’s version constraints 13 | • is safe to run multiple times, to bring the working directory up to date with changes in the configuration 14 | • does not delete the existing configuration or state 15 | 16 | # **terraform validate** 17 | • validates syntactically for format and correctness. 18 | • is used to validate/check the syntax of the Terraform files. 19 | • verifies whether a configuration is syntactically valid and internally consistent, regardless of any provided variables or existing state. 20 | • A syntax check is done on all the terraform files in the directory, and will display an error if any of the files doesn’t validate. 21 | 22 | # **terraform plan** 23 | • create a execution plan 24 | • traverses each vertex and requests each provider using parallelism 25 | • calculates the difference between the last-known state and 26 | the current state and presents this difference as the output of the terraform plan operation to user in their terminal 27 | • does not modify the infrastructure or state. 28 | • allows a user to see which actions Terraform will perform prior to making any changes to reach the desired state 29 | • will scan all *.tf  files in the directory and create the plan 30 | • will perform refresh for each resource and might hit rate limiting issues as it calls provider APIs 31 | • all resources refresh can be disabled or avoided using 32 | -refresh=false or 33 | target=xxxx or 34 | break resources into different directories. 35 | • supports -out to save the plan 36 | 37 | #**terraform apply** 38 | • apply changes to reach the desired state. 39 | • scans the current directory for the configuration and applies the changes appropriately. 40 | • can be provided with a explicit plan, saved as out from terraform plan 41 | • If no explicit plan file is given on the command line, terraform apply will create a new plan automatically 42 | and prompt for approval to apply it 43 | • will modify the infrastructure and the state. 44 | • if a resource successfully creates but fails during provisioning, 45 | - Terraform will error and mark the resource as “tainted”. 46 | - A resource that is tainted has been physically created, but can’t be considered safe to use since provisioning failed. 47 | - Terraform also does not automatically roll back and destroy the resource during the apply when the failure happens, because that would go against the execution plan: the execution plan would’ve said a resource will be created, but does not say it will ever be deleted. 48 | • does not import any resource. 49 | • supports -auto-approve to apply the changes without asking for a confirmation 50 | • supports -target to apply a specific module 51 | 52 | #**terraform refresh** 53 | • used to reconcile the state Terraform knows about (via its state file) with the real-world infrastructure 54 | • does not modify infrastructure, but does modify the state file 55 | destroy 56 | • destroy the infrastructure and all resources 57 | • modifies both state and infrastructure 58 | • terraform destroy -target can be used to destroy targeted resources 59 | • terraform plan -destroy allows creation of destroy plan 60 | 61 | #**terraform import** 62 | • helps import already-existing external resources, not managed by Terraform, into Terraform state and allow it to manage those resources 63 | • Terraform is not able to auto-generate configurations for those imported modules, for now, and requires you to first write the resource definition in Terraform and then import this resource 64 | 65 | #**terraform taint** 66 | • marks a Terraform-managed resource as tainted, forcing it to be destroyed and recreated on the next apply. 67 | • will not modify infrastructure, but does modify the state file in order to mark a resource as tainted. Infrastructure and state are changed in next apply. 68 | • can be used to taint a resource within a module 69 | 70 | #**terraform fmt** 71 | • format to lint the code into a standard format 72 | 73 | #**terraform console** 74 | • command provides an interactive console for evaluating expressions. 75 | -------------------------------------------------------------------------------- /02 - Command basics/Credentials.md: -------------------------------------------------------------------------------- 1 | The AWS provider offers a flexible means of providing credentials for authentication. The following methods are supported, in this order, and explained below: 2 | 3 | - **Static credentials** 4 | provider "aws" { 5 | region = "us-west-2" 6 | access_key = "my-access-key" 7 | secret_key = "my-secret-key" 8 | } 9 | 10 | - **Environment variables** 11 | $ export AWS_ACCESS_KEY_ID="accesskey" 12 | $ export AWS_SECRET_ACCESS_KEY="secretkey" 13 | $ export AWS_DEFAULT_REGION="us-west-2" 14 | 15 | - **Shared credentials/configuration file** 16 | provider "aws" { 17 | region = "us-west-2" 18 | shared_credentials_file = "/Users/tf_user/.aws/creds" 19 | profile = "dev" 20 | } 21 | -------------------------------------------------------------------------------- /02 - Command basics/Project1/Project1-solution/project1-solution.md: -------------------------------------------------------------------------------- 1 | # Solution for project 1 2 | 1) Create a new folder called: Project 1 3 | 2) Create a VPC named "FirstVPC" 4 | 3) CIDR range : 192.168.0.0/24 5 | ================================================================= 6 | 7 | # Terraform Settings Block 8 | terraform { 9 | required_version = "~> 1.0" 10 | required_providers { 11 | aws = { 12 | source = "hashicorp/aws" 13 | version = "~> 3.0" 14 | # Optional but recommended in production 15 | } 16 | } 17 | } 18 | 19 | # Provider Block 20 | provider "aws" { 21 | profile = "default" 22 | region = "us-west-2" 23 | } 24 | 25 | # Resource Block 26 | 27 | resource "aws_vpc" "project1vpc" { 28 | cidr_block = "192.168.0.0/24" 29 | tags = { 30 | Name = "FirstVPC" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /02 - Command basics/Project1/Project1-solution/vpc.tf: -------------------------------------------------------------------------------- 1 | # Terraform Settings Block 2 | terraform { 3 | required_version = "~> 1.0" 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | # Optional but recommended in production 9 | } 10 | } 11 | } 12 | 13 | # Provider Block 14 | provider "aws" { 15 | profile = "default" 16 | region = "us-west-2" 17 | } 18 | 19 | # Resource Block 20 | 21 | resource "aws_vpc" "project1vpc" { 22 | cidr_block = "192.168.0.0/24" 23 | tags = { 24 | Name = "FirstVPC" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /02 - Command basics/Project1/project1.md: -------------------------------------------------------------------------------- 1 | # A simple project 2 | 1) Create a new folder /directory called: Project 1 3 | 2) Create a VPC named "FirstVPC" 4 | 3) CIDR range : 192.168.0.0/24 5 | -------------------------------------------------------------------------------- /02 - Command basics/ReadME.md: -------------------------------------------------------------------------------- 1 | # Terraform Command Basics 2 | 3 | ## Step-01: Terraform configuration files 4 | - Terraform uses declarative syntax to describe your Infrastructure as Code (IaC) infrastructure 5 | and then persist it in configuration files that can be shared, reviewed, edited, versioned, 6 | preserved, and reused. 7 | - Terraform configuration files can use either of two formats: Terraform domain-specific 8 | language (HashiCorp Configuration Language format [HCL]), which is the recommended 9 | approach, or JSON format if the files need to be machine-readable. 10 | - Configuration files that use the HCL format end with the .tf file extension; 11 | - Those using JSON format end with the .tf.json file extension. 12 | - The Terraform format is human-readable, while the JSON format is machine readable 13 | 14 | 15 | ## Step-01: Introduction to Terraform workflow - main commands 16 | **Terraform init**: 17 | - Used to initialize a working directory containing terraform config files. 18 | - This is the first command that should be run after writing a new terraform configuration file. 19 | - It downloads providers and modules 20 | **Terraform validate**: 21 | - Validates the configuration files in the respective directory to ensure that they are syntactically valid and internally consistent. 22 | **Terraform plan**: 23 | - Creates an execution plan 24 | - Terraform performs a refresh and determines what actions are necessary to achieve the desired state specified in the configuration files 25 | **Terraform apply**: 26 | - Used to apply the changes required to reach the desired state of the configuration 27 | - By default, apply scans the current directory for the configuration and applies the changes appropriately. 28 | - The state file is created when apply is ran the first time. 29 | **Terraform destroy**: 30 | - Use to destroy terraform managed infrastructure. 31 | - This will ask for confirmation before destroying. 32 | 33 | ## Step-02: Review terraform manifest for EC2 Instance 34 | - **Pre-Conditions-1:** Ensure you have **default-vpc** in that respective region 35 | - **Pre-Conditions-2:** Ensure AMI you are provisioning exists in that region if not update AMI ID 36 | - **Pre-Conditions-3:** Verify your AWS Credentials in **$HOME/.aws/credentials** 37 | 38 | ``` 39 | # Terraform Settings Block 40 | terraform { 41 | required_version = "~> 1.0" 42 | required_providers { 43 | aws = { 44 | source = "hashicorp/aws" 45 | version = "~> 3.0" # Optional but recommended in production 46 | } 47 | } 48 | } 49 | 50 | # Provider Block 51 | provider "aws" { 52 | profile = "default" 53 | region = "us-west-2" 54 | } 55 | 56 | # Resource Block 57 | resource "aws_instance" "ec2demo" { 58 | ami = "ami-0e5b6b6a9f3db6db8" 59 | instance_type = "t2.micro" 60 | } 61 | ``` 62 | 63 | ## Step-03: Terraform Core Commands 64 | 65 | # Initialize Terraform 66 | terraform init 67 | 68 | # Terraform Validate 69 | terraform validate 70 | 71 | # Terraform Plan to Verify what it is going to create / update / destroy 72 | terraform plan 73 | 74 | # Terraform Apply to Create EC2 Instance 75 | terraform apply 76 | 77 | 78 | ## Step-04: Verify the EC2 Instance in AWS Management Console 79 | - Go to AWS Management Console -> Services -> EC2 80 | - Verify newly created EC2 instance 81 | 82 | 83 | ## Step-05: Destroy Infrastructure 84 | 85 | # Destroy EC2 Instance 86 | terraform destroy 87 | -------------------------------------------------------------------------------- /02 - Command basics/manifests/ec2instance.tf: -------------------------------------------------------------------------------- 1 | # Terraform Settings Block 2 | terraform { 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "~> 3.0" # Optional but recommended in production 7 | } 8 | } 9 | } 10 | 11 | # Provider Block 12 | provider "aws" { 13 | profile = "Kenmak" # AWS Credentials Profile configured on your local desktop terminal $HOME/.aws/credentials 14 | region = "us-west-2" 15 | } 16 | 17 | # Resource Block 18 | 19 | resource "aws_instance" "ec2demo" { 20 | ami = "ami-0e5b6b6a9f3db6db8" # Amazon Linux in us-west-2, update as per your region 21 | instance_type = "t2.micro" 22 | 23 | tags = { 24 | Name = "myec2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /03 - Language Syntax/ReadME.md: -------------------------------------------------------------------------------- 1 | # Terraform Configuration Language Syntax 2 | 3 | ## **Step-01: Blocks** 4 | https://www.terraform.io/docs/configuration/syntax.html 5 | # a) **Understand Blocks** 6 | - Terraform Settings Block 7 | - Provider Block 8 | - Resource Block 9 | - Input Variables Block 10 | - Output Values Block 11 | - Local Values Block 12 | - Data Sources Block 13 | - Modules Block 14 | 15 | - A block is a container for other content: 16 | # Template 17 | 18 | "" "" { 19 | # Block body 20 | = # Argument 21 | } 22 | 23 | # AWS Example 24 | resource "aws_instance" "ec2demo" { 25 | # BLOCK BODY 26 | ami = "ami-04d29b6f966df1537" # Argument 27 | instance_type = var.instance_type # Argument with value as expression (Variable value replaced from varibales.tf 28 | 29 | network_interface { 30 | # ... 31 | } 32 | } 33 | 34 | - A block has a type (resource in this example). Each block type defines how many labels must follow the type keyword. The resource block type expects two labels, which are aws_instance and ec2demo in the example above. A particular block type may have any number of required labels, or it may require none as with the nested network_interface block type. 35 | 36 | - After the block type keyword and any labels, the block body is delimited by the { and } characters. Within the block body, further arguments and blocks may be nested, creating a hierarchy of blocks and their associated arguments. 37 | 38 | ## **Step-02: Arguments, Expressions, Attributes & Meta-Arguments** 39 | 40 | # Arguments 41 | -They assign a value to a name. They appear within blocks. Arguments can be required or optional. 42 | 43 | # Expressions 44 | - They represent a value, either literally or by referencing and combining other values. They appear as values for arguments, or within other expressions. 45 | 46 | # Attributes 47 | - They represent a named piece of data that belongs to some kind of object. The value of an attribute can be referenced in expressions using a dot-separated notation, like aws_instance.example.id. 48 | - The format looks like `resource_type.resource_name.attribute_name` 49 | 50 | # Identifiers 51 | - Argument names, block type names, and the names of most Terraform-specific constructs like resources, input variables, etc. are all identifiers. 52 | 53 | - Identifiers can contain letters, digits, underscores (_), and hyphens (-). The first character of an identifier must not be a digit, to avoid ambiguity with literal numbers. 54 | 55 | # Comments 56 | - The Terraform language supports three different syntaxes for comments: 57 | 58 | The # begins a single-line comment, ending at the end of the line. 59 | // also begins a single-line comment, as an alternative to #. 60 | /* and */ are start and end delimiters for a comment that might span over multiple lines. 61 | The # single-line comment style is the default comment style and should be used in most cases. Automatic configuration formatting tools may automatically transform // comments into # comments, since the double-slash style is not idiomatic. 62 | 63 | # Meta-Arguments 64 | (https://www.terraform.io/docs/language/meta-arguments/) 65 | - Meta-Arguments change a resource type's behavior (Example: count, for_each) 66 | 67 | **depends_on** 68 | - The depends_on meta-argument, if present, must be a list of references to other resources or child modules in the same calling module. Arbitrary expressions are not allowed in the depends_on argument value, because its value must be known before Terraform knows resource relationships and thus before it can safely evaluate expressions. 69 | 70 | **Count** 71 | - The count meta-argument accepts numeric expressions. However, unlike most arguments, the count value must be known before Terraform performs any remote resource actions. This means count can't refer to any resource attributes that aren't known until after a configuration is applied 72 | - In blocks where count is set, an additional count object is available in expressions, so you can modify the configuration of each instance. This object has one attribute: **count.index** — The distinct index number (starting with 0) corresponding to this instance. 73 | 74 | **for_each** 75 | - If your instances are almost identical, count is appropriate. If some of their arguments need distinct values that can't be directly derived from an integer, it's safer to use for_each. 76 | - The for_each meta-argument accepts a map or a set of strings, and creates an instance for each item in that map or set. Each instance has a distinct infrastructure object associated with it, and each is separately created, updated, or destroyed when the configuration is applied. 77 | - In blocks where for_each is set, an additional each object is available in expressions, so you can modify the configuration of each instance. This object has two attributes: 78 | 79 | each.key — The map key (or set member) corresponding to this instance. 80 | each.value — The map value corresponding to this instance. (If a set was provided, this is the same as each.key.) 81 | - The for_each value must be a map or set with one element per desired resource instance. When providing a set, you must use an expression that explicitly returns a set value, like the toset function; to prevent unwanted surprises during conversion, the for_each argument does not implicitly convert lists or tuples to sets. 82 | -toset converts its argument to a set value. Explicit type conversions are rarely necessary in Terraform because it will convert types automatically where required. Use the explicit type conversion functions only to normalize types returned in module outputs. Pass a list value to toset to convert it to a set, which will remove any duplicate elements and discard the ordering of the elements. 83 | 84 | # map 85 | resource "azurerm_resource_group" "rg" { 86 | for_each = { 87 | a_group = "eastus" 88 | another_group = "westus2" 89 | } 90 | name = each.key 91 | location = each.value 92 | } 93 | 94 | # Set of strings 95 | resource "aws_iam_user" "the-accounts" { 96 | for_each = toset( ["Todd", "James", "Alice", "Dottie"] ) 97 | name = each.key 98 | } 99 | 100 | **lifecycle** 101 | -------------------------------------------------------------------------------- /03 - Language Syntax/manifests/app1-install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Instance Identity Metadata Reference - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html 3 | sudo yum update -y 4 | sudo yum install -y httpd 5 | sudo systemctl enable httpd 6 | sudo service httpd start 7 | sudo echo '

Welcome to Landmark Technologies

' | sudo tee /var/www/html/index.html 8 | sudo mkdir /var/www/html/app1 9 | sudo echo '

Welcome to Landmark Technologies

Terraform Demo

Application Version: V1

' | sudo tee /var/www/html/app1/index.html 10 | sudo curl http://169.254.169.254/latest/dynamic/instance-identity/document -o /var/www/html/app1/metadata.html 11 | -------------------------------------------------------------------------------- /03 - Language Syntax/manifests/ec2instance.tf: -------------------------------------------------------------------------------- 1 | # Resource: EC2 Instance 2 | resource "aws_instance" "myec2vm" { 3 | ami = "ami-0e5b6b6a9f3db6db8" 4 | instance_type = "t3.micro" 5 | user_data = file("${path.module}/app1-install.sh") 6 | tags = { 7 | "Name" = "EC2 Demo" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /03 - Language Syntax/manifests/version.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | 3 | terraform { 4 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 5 | required_providers { 6 | aws = { 7 | source = "hashicorp/aws" 8 | version = "~> 3.0" 9 | } 10 | } 11 | } 12 | 13 | 14 | # Provider Block 15 | provider "aws" { 16 | region = "us-west-2" 17 | } 18 | 19 | /* 20 | Note-1: AWS Credentials Profile (profile = "default") configured on your local desktop terminal 21 | $HOME/.aws/credentials 22 | */ 23 | -------------------------------------------------------------------------------- /03 - Language Syntax/top-level-blocks-sample.md: -------------------------------------------------------------------------------- 1 | 2 | #Block-1: **Terraform Settings Block** 3 | terraform { 4 | required_version = "~> 1.0" 1.1.4/5/6/7 1.2/3/4/5 1.1.4/5/6/7 5 | required_providers { 6 | aws = { 7 | source = "hashicorp/aws" 8 | version = "~> 3.0" 9 | } 10 | } 11 | 12 | 13 | # Adding Backend as S3 for Remote State Storage with State Locking 14 | backend "s3" { 15 | bucket = "terraform-mylandmark" 16 | key = "prod/terraform.tfstate" 17 | region = "us-west-2" 18 | # For State Locking 19 | dynamodb_table = "terraform-lock" 20 | } 21 | } 22 | 23 | resource "aws_dynamodb_table" “tf_lock" { 24 | name = "terraform-lock" 25 | hash_key = "LockID" 26 | read_capacity = 3 27 | write_capacity = 3 28 | attribute { 29 | name = "LockID" 30 | type = "S" 31 | } 32 | tags { 33 | Name = "Terraform Lock Table" 34 | } 35 | } 36 | 37 | 38 | # Block-2: **Provider Block** 39 | provider "aws" { 40 | profile = "default" # AWS Credentials Profile configured on your local desktop terminal $HOME/.aws/credentials 41 | region = "us-west-2" 42 | } 43 | 44 | # Block-3: **Resource Block** 45 | resource "aws_instance" "class25" { 46 | ami = "ami-0e5b6b6a9f3db6db8" # Amazon Linux 47 | instance_type = var.instance_type 48 | } 49 | 50 | # Block-4: **Input Variables Block** 51 | variable "instance_type" { 52 | default = "t2.micro" 53 | description = "EC2 Instance Type" 54 | type = string 55 | } 56 | 57 | # Block-5: **Output Values Block** 58 | output "ec2_instance_publicip" { 59 | description = "EC2 Instance Public IP" 60 | value = aws_instance.class25.public_ip 61 | } 62 | 63 | # Block-6: **Local Values Block** 64 | # Create S3 Bucket - with Input Variables & Local Values 65 | locals { 66 | name = "${var.app_name}-${var.environment_name}" 67 | } 68 | bucket_name = locals.name 69 | 70 | 71 | # Block-7: **Data sources Block** 72 | # Get latest AMI ID for Amazon Linux2 OS 73 | data "aws_ami" "amzlinux" { 74 | most_recent = true 75 | owners = ["amazon"] 76 | 77 | filter { 78 | name = "name" 79 | values = ["amzn2-ami-hvm-*"] 80 | } 81 | 82 | filter { 83 | name = "root-device-type" 84 | values = ["ebs"] 85 | } 86 | 87 | filter { 88 | name = "virtualization-type" 89 | values = ["hvm"] 90 | } 91 | 92 | filter { 93 | name = "architecture" 94 | values = ["x86_64"] 95 | } 96 | 97 | } 98 | 99 | 100 | # Block-8: **Modules Block** 101 | # AWS EC2 Instance Module 102 | 103 | module "ec2_cluster" { 104 | source = "terraform-aws-modules/ec2-instance/aws" 105 | version = "~> 2.0" 106 | 107 | name = "my-modules-demo" 108 | instance_count = 2 109 | 110 | ami = data.aws_ami.amzlinux.id 111 | instance_type = "t2.micro" 112 | key_name = "terraform-key" 113 | monitoring = true 114 | vpc_security_group_ids = ["sg-08b25c5a5bf489ffa"] # Get Default VPC Security Group ID and replace 115 | subnet_id = "subnet-4ee95470" # Get one public subnet id from default vpc and replace 116 | user_data = file("apache-install.sh") 117 | 118 | tags = { 119 | Terraform = "true" 120 | Environment = "dev" 121 | } 122 | } 123 | 124 | -------------------------------------------------------------------------------- /04 - Settings/Project2/Project-2.md: -------------------------------------------------------------------------------- 1 | # Project 2 2 | 1) Create an ec2 instance 3 | 2) Attach an elastic IP to the instance 4 | 3) Output the value of the public IP of the eip. 5 | -------------------------------------------------------------------------------- /04 - Settings/Project2/Project2 solution/Project2-solution.md: -------------------------------------------------------------------------------- 1 | # Project 2 solution 2 | 1) Create an ec2 instance 3 | 2) Attach an elastic IP to the instance 4 | 3) Output the value of the public IP of the eip. 5 | 6 | # **Terraform block** 7 | ```t 8 | terraform { 9 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 10 | required_providers { 11 | aws = { 12 | source = "hashicorp/aws" 13 | version = "~> 3.0" 14 | } 15 | } 16 | } 17 | 18 | # Provider Block 19 | provider "aws" { 20 | region = "us-west-2" 21 | } 22 | 23 | resource "aws_instance" "ec2" { 24 | ami = "ami-0e5b6b6a9f3db6db8" 25 | instance_type = "t2.micro" 26 | } 27 | 28 | # Refer to the arguments section for the eip (https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip#argument-reference) 29 | resource "aws_eip" "elasticeip" { 30 | instance = aws_instance.ec2.id 31 | } 32 | # Refer to the attribute section for the eip (https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip#attributes-reference) 33 | output "EIP" { 34 | value = aws_eip.elasticeip.public_ip 35 | } 36 | -------------------------------------------------------------------------------- /04 - Settings/ReadME.md: -------------------------------------------------------------------------------- 1 | # Terraform Settings, Providers & Resource Blocks 2 | ## Step-01: Introduction 3 | - [Terraform Settings](https://www.terraform.io/docs/language/settings/index.html) 4 | - [Terraform Providers](https://www.terraform.io/docs/providers/index.html) 5 | - [Terraform Resources](https://www.terraform.io/docs/language/resources/index.html) 6 | - [Terraform File Function](https://www.terraform.io/docs/language/functions/file.html) 7 | - Create EC2 Instance using Terraform and provision a webserver with userdata. 8 | 9 | ## Step-02: In versions.tf - Create Terraform Settings Block 10 | - Understand about [Terraform Settings Block](https://www.terraform.io/docs/language/settings/index.html) and create it 11 | ```t 12 | terraform { 13 | required_version = "~> 0.14." # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 14 | required_providers { 15 | aws = { 16 | source = "hashicorp/aws" 17 | version = "~> 3.0" 18 | } 19 | } 20 | } 21 | ``` 22 | 23 | ## Step-03: In versions.tf - Create Terraform Providers Block 24 | - Understand about [Terraform Providers](https://www.terraform.io/docs/providers/index.html) 25 | - Configure AWS Credentials in the AWS CLI if not configured 26 | ```t 27 | # Verify AWS Credentials 28 | cat $HOME/.aws/credentials 29 | ``` 30 | - Create [AWS Providers Block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication) 31 | ```t 32 | # Provider Block 33 | provider "aws" { 34 | region = us-west-2 35 | profile = "default" 36 | } 37 | ``` 38 | 39 | ## Step-04: In ec2instance.tf - Create Resource Block 40 | - Understand about [Resources](https://www.terraform.io/docs/language/resources/index.html) 41 | - Create [EC2 Instance Resource](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) 42 | - Understand about [File Function](https://www.terraform.io/docs/language/functions/file.html) 43 | - Understand about [Resources - Argument Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#argument-reference) 44 | - Understand about [Resources - Attribute Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#attributes-reference) 45 | ```t 46 | # Resource: EC2 Instance 47 | resource "aws_instance" "myec2vm" { 48 | ami = "ami-0533f2ba8a1995cf9" 49 | instance_type = "t3.micro" 50 | user_data = file("${path.module}/app1-install.sh") 51 | tags = { 52 | "Name" = "EC2 Demo" 53 | } 54 | } 55 | ``` 56 | 57 | 58 | ## Step-05: Review file app1-install.sh 59 | ```sh 60 | #! /bin/bash 61 | # Instance Identity Metadata Reference - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html 62 | sudo yum update -y 63 | sudo yum install -y httpd 64 | sudo systemctl enable httpd 65 | sudo service httpd start 66 | sudo echo '

Welcome to Landmark Technologies

' | sudo tee /var/www/html/index.html 67 | sudo mkdir /var/www/html/app1 68 | sudo echo '

Welcome to Landmark Technologies

Terraform Demo

Application Version: V1

' | sudo tee /var/www/html/app1/index.html 69 | sudo curl http://169.254.169.254/latest/dynamic/instance-identity/document -o /var/www/html/app1/metadata.html 70 | ``` 71 | 72 | ## Step-06: Execute Terraform Commands 73 | ```t 74 | # Terraform Initialize 75 | terraform init 76 | Observation: 77 | 1) Initialized Local Backend 78 | 2) Downloaded the provider plugins (initialized plugins) 79 | 3) Review the folder structure ".terraform folder" 80 | 81 | # Terraform Validate 82 | terraform validate 83 | Observation: 84 | 1) If any changes to files, those will come as printed in stdout (those file names will be printed in CLI) 85 | 86 | # Terraform Plan 87 | terraform plan 88 | Observation: 89 | 1) No changes - Just prints the execution plan 90 | 91 | # Terraform Apply 92 | terraform apply 93 | [or] 94 | terraform apply -auto-approve 95 | Observations: 96 | 1) Create resources on cloud 97 | 2) Created terraform.tfstate file when you run the terraform apply command 98 | ``` 99 | 100 | ## Step-07: Access Application 101 | - **Important Note:** verify if default VPC security group has a rule to allow port 80 102 | ```t 103 | # Access index.html 104 | http:///index.html 105 | http:///app1/index.html 106 | 107 | # Access metadata.html 108 | http:///app1/metadata.html 109 | ``` 110 | 111 | ## Step-08: Terraform State - Basics 112 | - Understand about Terraform State 113 | - Terraform State file `terraform.tfstate` 114 | - Understand about `Desired State` and `Current State` 115 | 116 | 117 | ## Step-09: Clean-Up 118 | ```t 119 | # Terraform Destroy 120 | terraform plan -destroy # You can view destroy plan using this command 121 | terraform destroy 122 | 123 | # Clean-Up Files 124 | rm -rf .terraform* 125 | rm -rf terraform.tfstate* 126 | ``` 127 | 128 | 129 | ## Step-10: Additional Observations - Concepts we will learn in next section 130 | - EC2 Instance created we didn't associate a EC2 Key pair to login to EC2 Instance 131 | - Terraform Resource Argument - `Key Name` 132 | - AMI Name is static - How to make it Dynamic ? 133 | - Use `Terraform Datasources` concept 134 | - We didn't create multiple instances of same EC2 Instance 135 | - Resource Meta-Argument: `count` 136 | - We didn't add any variables for parameterizations 137 | - Terraform `Input Variable` Basics 138 | - We didn't extract any information on terminal about instance information 139 | - Terraform `Outputs` 140 | - Create second resource only after first resource is created 141 | - Defining Explicit Dependency in Terraform using Resource Meta-Argument `depends_on` 142 | 143 | -------------------------------------------------------------------------------- /04 - Settings/manifests/app1-install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Instance Identity Metadata Reference - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html 3 | sudo yum update -y 4 | sudo yum install -y httpd 5 | sudo systemctl enable httpd 6 | sudo service httpd start 7 | sudo echo '

Welcome to Landmark Technologies

' | sudo tee /var/www/html/index.html 8 | sudo mkdir /var/www/html/app1 9 | sudo echo '

Welcome to Landmark Technologies

Terraform Demo

Application Version: V1

' | sudo tee /var/www/html/app1/index.html 10 | sudo curl http://169.254.169.254/latest/dynamic/instance-identity/document -o /var/www/html/app1/metadata.html 11 | 12 | 13 | # Ensure that you update the inbound rules on the security group of your instance. Add http port 80 14 | -------------------------------------------------------------------------------- /04 - Settings/manifests/ec2instance.tf: -------------------------------------------------------------------------------- 1 | # Resource: EC2 Instance 2 | resource "aws_instance" "myec2" { 3 | ami = "ami-0e5b6b6a9f3db6db8" 4 | instance_type = "t2.micro" 5 | user_data = file("${path.module}/app1-install.sh") 6 | tags = { 7 | "Name" = "EC2 Demo" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /04 - Settings/manifests/providers.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | # Provider Block 12 | provider "aws" { 13 | region = "us-west-2" 14 | profile = "default" 15 | } 16 | 17 | /* 18 | Note-1: AWS Credentials Profile (profile = "default") configured on your local desktop terminal 19 | $HOME/.aws/credentials 20 | */ 21 | # 22 | This command unsets the environmental variables previously set incase you encounter an error about invalid credentials. 23 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/ReadME.md: -------------------------------------------------------------------------------- 1 | # Terraform Variables and Datasources 2 | 3 | ## Step-00: Pre-requisite Note 4 | - Create a `key pair` in AWS EC2 Key pairs which we will reference in our EC2 Instance 5 | 6 | ## Step-01: Introduction 7 | ### Terraform Concepts 8 | - Terraform Input Variables 9 | - Terraform Datasources 10 | - Terraform Output Values 11 | 12 | ### What are we going to learn ? 13 | 1. Learn about Terraform `Input Variable` basics 14 | - AWS Region 15 | - Instance Type 16 | - Key Name 17 | 2. Define `Security Groups` and Associate them as a `List item` to AWS EC2 Instance 18 | - vpc-ssh 19 | - vpc-web 20 | 3. Learn about Terraform `Output Values` 21 | - Public IP 22 | - Public DNS 23 | 4. Get latest EC2 AMI ID Using `Terraform Datasources` concept 24 | 5. We are also going to use existing EC2 Key pair `Automationkey` 25 | 6. Use all the above to create an EC2 Instance in default VPC 26 | 27 | 28 | ## Step-02: c2-variables.tf - Define Input Variables in Terraform 29 | - [Terraform Input Variables](https://www.terraform.io/docs/language/values/variables.html) 30 | 31 | ```t 32 | # AWS Region 33 | variable "aws_region" { 34 | description = "Region in which AWS Resources to be created" 35 | type = string 36 | default = "us-east-1" 37 | } 38 | 39 | # AWS EC2 Instance Type 40 | variable "instance_type" { 41 | description = "EC2 Instance Type" 42 | type = string 43 | default = "t3.micro" 44 | } 45 | 46 | # AWS EC2 Instance Key Pair 47 | variable "instance_keypair" { 48 | description = "AWS EC2 Key pair that need to be associated with EC2 Instance" 49 | type = string 50 | default = "terraform-key" 51 | } 52 | ``` 53 | - Reference the variables in respective `.tf`fies 54 | ```t 55 | # versions.tf 56 | region = var.aws_region 57 | 58 | # ec2instance.tf 59 | instance_type = var.instance_type 60 | key_name = var.instance_keypair 61 | ``` 62 | 63 | ## Step-03: ec2securitygroups.tf - Define Security Group Resources in Terraform 64 | - [Resource: aws_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) 65 | ```t 66 | # Create Security Group - SSH Traffic 67 | resource "aws_security_group" "vpc-ssh" { 68 | name = "vpc-ssh" 69 | description = "Dev VPC SSH" 70 | ingress { 71 | description = "Allow Port 22" 72 | from_port = 22 73 | to_port = 22 74 | protocol = "tcp" 75 | cidr_blocks = ["0.0.0.0/0"] 76 | } 77 | egress { 78 | description = "Allow all ip and ports outboun" 79 | from_port = 0 80 | to_port = 0 81 | protocol = "-1" 82 | cidr_blocks = ["0.0.0.0/0"] 83 | } 84 | } 85 | 86 | # Create Security Group - Web Traffic 87 | resource "aws_security_group" "vpc-web" { 88 | name = "vpc-web" 89 | description = "Dev VPC web" 90 | ingress { 91 | description = "Allow Port 80" 92 | from_port = 80 93 | to_port = 80 94 | protocol = "tcp" 95 | cidr_blocks = ["0.0.0.0/0"] 96 | } 97 | 98 | ingress { 99 | description = "Allow Port 443" 100 | from_port = 443 101 | to_port = 443 102 | protocol = "tcp" 103 | cidr_blocks = ["0.0.0.0/0"] 104 | } 105 | 106 | egress { 107 | description = "Allow all ip and ports outbound" 108 | from_port = 0 109 | to_port = 0 110 | protocol = "-1" 111 | cidr_blocks = ["0.0.0.0/0"] 112 | } 113 | } 114 | ``` 115 | - Reference the security groups in `ec2instance.tf` file as a list item 116 | ```t 117 | # List Item 118 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 119 | ``` 120 | 121 | ## Step-04: ami-datasource.tf - Define Get Latest AMI ID for Amazon Linux2 OS 122 | - [Data Source: aws_ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) 123 | ```t 124 | # Get latest AMI ID for Amazon Linux2 OS 125 | # Get Latest AWS AMI ID for Amazon2 Linux 126 | data "aws_ami" "amzlinux2" { 127 | most_recent = true 128 | owners = [ "amazon" ] 129 | filter { 130 | name = "name" 131 | values = [ "amzn2-ami-hvm-*-gp2" ] 132 | } 133 | filter { 134 | name = "root-device-type" 135 | values = [ "ebs" ] 136 | } 137 | filter { 138 | name = "virtualization-type" 139 | values = [ "hvm" ] 140 | } 141 | filter { 142 | name = "architecture" 143 | values = [ "x86_64" ] 144 | } 145 | } 146 | ``` 147 | - Reference the datasource in `c5-ec2instance.tf` file 148 | ```t 149 | # Reference Datasource to get the latest AMI ID 150 | ami = data.aws_ami.amzlinux2.id 151 | ``` 152 | 153 | ## Step-05: c5-ec2instance.tf - Define EC2 Instance Resource 154 | - [Resource: aws_instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) 155 | ```t 156 | # EC2 Instance 157 | resource "aws_instance" "myec2vm" { 158 | ami = data.aws_ami.amzlinux2.id 159 | instance_type = var.instance_type 160 | user_data = file("${path.module}/app1-install.sh") 161 | key_name = var.instance_keypair 162 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 163 | tags = { 164 | "Name" = "EC2 Demo 2" 165 | } 166 | } 167 | ``` 168 | 169 | 170 | ## Step-06: c6-outputs.tf - Define Output Values 171 | - [Output Values](https://www.terraform.io/docs/language/values/outputs.html) 172 | ```t 173 | # Terraform Output Values 174 | output "instance_publicip" { 175 | description = "EC2 Instance Public IP" 176 | value = aws_instance.myec2vm.public_ip 177 | } 178 | 179 | output "instance_publicdns" { 180 | description = "EC2 Instance Public DNS" 181 | value = aws_instance.myec2vm.public_dns 182 | } 183 | ``` 184 | 185 | ## Step-07: Execute Terraform Commands 186 | ```t 187 | # Terraform Initialize 188 | terraform init 189 | Observation: 190 | 1) Initialized Local Backend 191 | 2) Downloaded the provider plugins (initialized plugins) 192 | 3) Review the folder structure ".terraform folder" 193 | 194 | # Terraform Validate 195 | terraform validate 196 | Observation: 197 | 1) If any changes to files, those will come as printed in stdout (those file names will be printed in CLI) 198 | 199 | # Terraform Plan 200 | terraform plan 201 | Observation: 202 | 1) Verify the latest AMI ID picked and displayed in plan 203 | 2) Verify the number of resources that going to get created 204 | 3) Verify the variable replacements worked as expected 205 | 206 | # Terraform Apply 207 | terraform apply 208 | [or] 209 | terraform apply -auto-approve 210 | Observations: 211 | 1) Create resources on cloud 212 | 2) Created terraform.tfstate file when you run the terraform apply command 213 | 3) Verify the EC2 Instance AMI ID which got created 214 | ``` 215 | 216 | ## Step-08: Access Application 217 | ```t 218 | # Access index.html 219 | http:///index.html 220 | http:///app1/index.html 221 | 222 | # Access metadata.html 223 | http:///app1/metadata.html 224 | ``` 225 | 226 | ## Step-09: Clean-Up 227 | ```t 228 | # Terraform Destroy 229 | terraform plan -destroy # You can view destroy plan using this command 230 | terraform destroy 231 | 232 | # Clean-Up Files 233 | rm -rf .terraform* 234 | rm -rf terraform.tfstate* 235 | ``` 236 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/01-Basic-variables/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | instance_type = "t3.micro" 5 | key_name = "terraform-key" 6 | count = var.ec2_instance_count 7 | user_data = <<-EOF 8 | #!/bin/bash 9 | sudo yum update -y 10 | sudo yum install httpd -y 11 | sudo systemctl enable httpd 12 | sudo systemctl start httpd 13 | echo "

Welcome to Landmark Technologies!

" > /var/www/html/index.html 14 | EOF 15 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 16 | tags = { 17 | "Name" = "myec2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/01-Basic-variables/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/01-Basic-variables/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" # Amazon2 Linux AMI ID 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 1 18 | } 19 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/01-Basic-variables/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/02-Sensitive-input-variables/rds-db.tf: -------------------------------------------------------------------------------- 1 | # Warning: Never check sensitive values like usernames and passwords into source control. 2 | # Create RDS MySQL Database 3 | resource "aws_db_instance" "db1" { 4 | allocated_storage = 5 5 | engine = "mysql" 6 | instance_class = "db.t2.micro" 7 | name = "mydb1" 8 | username = var.db_username 9 | password = var.db_password 10 | skip_final_snapshot = true 11 | } 12 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/02-Sensitive-input-variables/secrets.tfvars: -------------------------------------------------------------------------------- 1 | db_username = "admin" 2 | db_password = "insecurepassword" 3 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/02-Sensitive-input-variables/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS Resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "db_username" { 9 | description = "AWS RDS Database Administrator Username" 10 | type = string 11 | sensitive = true 12 | } 13 | 14 | variable "db_password" { 15 | description = "AWS RDS Database Administrator Password" 16 | type = string 17 | sensitive = true 18 | } 19 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/02-Sensitive-input-variables/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/03-Assign-when-prompted/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | instance_type = var.ec2_instance_type 5 | key_name = "terraform-key" 6 | count = var.ec2_instance_count 7 | user_data = <<-EOF 8 | #!/bin/bash 9 | sudo yum update -y 10 | sudo yum install httpd -y 11 | sudo systemctl enable httpd 12 | sudo systemctl start httpd 13 | echo "

Welcome to Landmark Technologies !

" > /var/www/html/index.html 14 | EOF 15 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 16 | tags = { 17 | "Name" = "myec2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/03-Assign-when-prompted/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/03-Assign-when-prompted/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" # Amazon2 Linux AMI ID 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 1 18 | } 19 | 20 | # Assign When Prompted using CLI 21 | variable "ec2_instance_type" { 22 | description = "EC2 Instance Type" 23 | type = string 24 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/03-Assign-when-prompted/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/04-Override-default-with-cli-var/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | instance_type = var.ec2_instance_type 5 | key_name = "terraform-key" 6 | count = var.ec2_instance_count 7 | user_data = <<-EOF 8 | #!/bin/bash 9 | sudo yum update -y 10 | sudo yum install httpd -y 11 | sudo systemctl enable httpd 12 | sudo systemctl start httpd 13 | echo "

Welcome to Landmark Technologies!

" > /var/www/html/index.html 14 | EOF 15 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 16 | tags = { 17 | "Name" = "myec2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/04-Override-default-with-cli-var/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/04-Override-default-with-cli-var/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" # Amazon2 Linux AMI ID 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 2 18 | } 19 | 20 | variable "ec2_instance_type" { 21 | description = "EC2 Instance Type" 22 | type = string 23 | default = "t3.micro" 24 | } 25 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/04-Override-default-with-cli-var/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | /* 18 | Note-1: AWS Credentials Profile (profile = "default") configured on your local desktop terminal 19 | $HOME/.aws/credentials 20 | */ 21 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/05-Override-with-environmental-variables/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | instance_type = var.ec2_instance_type 5 | key_name = "terraform-key" 6 | count = var.ec2_instance_count 7 | user_data = <<-EOF 8 | #!/bin/bash 9 | sudo yum update -y 10 | sudo yum install httpd -y 11 | sudo systemctl enable httpd 12 | sudo systemctl start httpd 13 | echo "

Welcome to Landmark Technologies!

" > /var/www/html/index.html 14 | EOF 15 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 16 | tags = { 17 | "Name" = "myec2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/05-Override-with-environmental-variables/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/05-Override-with-environmental-variables/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" # Amazon2 Linux AMI ID 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 2 18 | } 19 | 20 | variable "ec2_instance_type" { 21 | description = "EC2 Instance Type" 22 | type = string 23 | default = "t3.micro" 24 | } 25 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/05-Override-with-environmental-variables/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/06-terraform-tfvars/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | instance_type = var.ec2_instance_type 5 | key_name = "terraform-key" 6 | count = var.ec2_instance_count 7 | user_data = <<-EOF 8 | #!/bin/bash 9 | sudo yum update -y 10 | sudo yum install httpd -y 11 | sudo systemctl enable httpd 12 | sudo systemctl start httpd 13 | echo "

Welcome to Landmark !

" > /var/www/html/index.html 14 | EOF 15 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 16 | tags = { 17 | "Name" = "myec2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/06-terraform-tfvars/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/06-terraform-tfvars/terraform.tfvars: -------------------------------------------------------------------------------- 1 | ec2_instance_count = 1 2 | ec2_instance_type = "t3.small" 3 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/06-terraform-tfvars/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" # Amazon2 Linux AMI ID 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 2 18 | } 19 | 20 | variable "ec2_instance_type" { 21 | description = "EC2 Instance Type" 22 | type = string 23 | default = "t3.micro" 24 | } 25 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/06-terraform-tfvars/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/07-tfvars-var-file/app.tfvars: -------------------------------------------------------------------------------- 1 | ec2_instance_type = "t2.medium" 2 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/07-tfvars-var-file/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | instance_type = var.ec2_instance_type 5 | key_name = "terraform-key" 6 | count = var.ec2_instance_count 7 | user_data = <<-EOF 8 | #!/bin/bash 9 | sudo yum update -y 10 | sudo yum install httpd -y 11 | sudo systemctl enable httpd 12 | sudo systemctl start httpd 13 | echo "

Welcome to Landmark Technologies!

" > /var/www/html/index.html 14 | EOF 15 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 16 | tags = { 17 | "Name" = "myec2vm" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/07-tfvars-var-file/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/07-tfvars-var-file/terraform.tfvars: -------------------------------------------------------------------------------- 1 | ec2_instance_count = 1 2 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/07-tfvars-var-file/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" # Amazon2 Linux AMI ID 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 2 18 | } 19 | 20 | variable "ec2_instance_type" { 21 | description = "EC2 Instance Type" 22 | type = string 23 | default = "t3.micro" 24 | } 25 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/07-tfvars-var-file/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/07-tfvars-var-file/web.tfvars: -------------------------------------------------------------------------------- 1 | ec2_instance_type = "t3.micro" 2 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/08-auto-tfvars/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | instance_type = var.ec2_instance_type 5 | key_name = "terraform-key" 6 | count = var.ec2_instance_count 7 | user_data = <<-EOF 8 | #!/bin/bash 9 | sudo yum update -y 10 | sudo yum install httpd -y 11 | sudo systemctl enable httpd 12 | sudo systemctl start httpd 13 | echo "

Welcome to Landmark Technologies!

" > /var/www/html/index.html 14 | EOF 15 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 16 | tags = { 17 | "Name" = "myec2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/08-auto-tfvars/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/08-auto-tfvars/terraform.tfvars: -------------------------------------------------------------------------------- 1 | ec2_instance_count = 1 2 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/08-auto-tfvars/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" # Amazon2 Linux AMI ID 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 2 18 | } 19 | 20 | variable "ec2_instance_type" { 21 | description = "EC2 Instance Type" 22 | type = string 23 | default = "t3.micro" 24 | } 25 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/08-auto-tfvars/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/08-auto-tfvars/web.auto.tfvars: -------------------------------------------------------------------------------- 1 | ec2_instance_type = "t2.medium" 2 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/09-input-variable-list/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | instance_type = var.ec2_instance_type[0] 5 | key_name = "terraform-key" 6 | count = var.ec2_instance_count 7 | user_data = <<-EOF 8 | #!/bin/bash 9 | sudo yum update -y 10 | sudo yum install httpd -y 11 | sudo systemctl enable httpd 12 | sudo systemctl start httpd 13 | echo "

Welcome to Landmark Technologies!

" > /var/www/html/index.html 14 | EOF 15 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 16 | tags = { 17 | "Name" = "myec2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/09-input-variable-list/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/09-input-variable-list/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" # Amazon2 Linux AMI ID 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 2 18 | } 19 | 20 | variable "ec2_instance_type" { 21 | description = "EC2 Instance Type" 22 | type = list(string) 23 | default = ["t3.micro", "t3.small", "t3.large"] 24 | } 25 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/09-input-variable-list/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/10-input-variable-map/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | #instance_type = var.ec2_instance_type[0] 5 | instance_type = var.ec2_instance_type_map["big-apps"] 6 | key_name = "terraform-key" 7 | count = var.ec2_instance_count 8 | user_data = <<-EOF 9 | #!/bin/bash 10 | sudo yum update -y 11 | sudo yum install httpd -y 12 | sudo systemctl enable httpd 13 | sudo systemctl start httpd 14 | echo "

Welcome to Landmark Technologies!

" > /var/www/html/index.html 15 | EOF 16 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 17 | tags = var.ec2_instance_tags 18 | } 19 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/10-input-variable-map/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/10-input-variable-map/variable.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" # Amazon2 Linux AMI ID 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 2 18 | } 19 | 20 | /* 21 | variable "ec2_instance_type" { 22 | description = "EC2 Instance Type" 23 | type = list(string) 24 | default = ["t3.micro", "t3.small", "t3.large"] 25 | } 26 | */ 27 | 28 | 29 | variable "ec2_instance_tags" { 30 | description = "EC2 Instance Tags" 31 | type = map(string) 32 | default = { 33 | "Name" = "ec2-web" 34 | "Tier" = "Web" 35 | } 36 | } 37 | 38 | variable "ec2_instance_type_map" { 39 | description = "EC2 Instance Type" 40 | type = map(string) 41 | default = { 42 | "small-apps" = "t3.micro" 43 | "medium-apps" = "t3.medium" 44 | "big-apps" = "t3.large" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/10-input-variable-map/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/File-function/apache-install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | sudo yum update -y 3 | sudo yum install -y httpd 4 | sudo systemctl enable httpd 5 | sudo service httpd start 6 | echo "

Welcome to Landmark Technologies!

" | sudo tee /var/www/html/index.html 7 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/File-function/ec2.tf: -------------------------------------------------------------------------------- 1 | # Create EC2 Instance 2 | resource "aws_instance" "my-ec2" { 3 | ami = var.ec2_ami_id 4 | instance_type = var.ec2_instance_type 5 | key_name = "terraform-key" 6 | count = var.ec2_instance_count 7 | user_data = file("apache-install.sh") 8 | /* 9 | user_data = <<-EOF 10 | #!/bin/bash 11 | sudo yum update -y 12 | sudo yum install httpd -y 13 | sudo systemctl enable httpd 14 | sudo systemctl start httpd 15 | echo "
Welcome to Landmark ! AWS Infra created using Terraform
" > /var/www/html/index.html 16 | EOF 17 | */ 18 | vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id] 19 | tags = { 20 | "Name" = "web" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/File-function/sg.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | egress { 13 | description = "Allow all IP and Ports outbound" 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | } 19 | } 20 | 21 | # Create Security Group - Web Traffic 22 | resource "aws_security_group" "vpc-web" { 23 | name = "vpc-web" 24 | description = "Dev VPC Web" 25 | 26 | ingress { 27 | description = "Allow Port 80" 28 | from_port = 80 29 | to_port = 80 30 | protocol = "tcp" 31 | cidr_blocks = ["0.0.0.0/0"] 32 | } 33 | 34 | ingress { 35 | description = "Allow Port 443" 36 | from_port = 443 37 | to_port = 443 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | 42 | egress { 43 | description = "Allow all IP and Ports outbound" 44 | from_port = 0 45 | to_port = 0 46 | protocol = "-1" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/File-function/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | variable "aws_region" { 3 | description = "Region in which AWS Resources to be created" 4 | type = string 5 | default = "us-west-1" 6 | } 7 | 8 | variable "ec2_ami_id" { 9 | description = "AMI ID" 10 | type = string 11 | default = "ami-0915bcb5fa77e4892" 12 | } 13 | 14 | variable "ec2_instance_count" { 15 | description = "EC2 Instance Count" 16 | type = number 17 | default = 1 18 | } 19 | 20 | variable "ec2_instance_type" { 21 | description = "EC2 Instance Type" 22 | type = string 23 | default = "t3.micro" 24 | } 25 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/Terraform-input-variables/File-function/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example1/data.tf: -------------------------------------------------------------------------------- 1 | data "aws_ami" "amzlinux2" { 2 | most_recent = true 3 | owners = ["amazon"] 4 | 5 | filter { 6 | name = "name" 7 | values = ["amzn2-ami-hvm-*-gp2"] 8 | } 9 | 10 | filter { 11 | name = "root-device-type" 12 | values = ["ebs"] 13 | } 14 | 15 | filter { 16 | name = "virtualization-type" 17 | values = ["hvm"] 18 | } 19 | filter { 20 | name = "architecture" 21 | values = ["x86_64"] 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example1/ec2.tf: -------------------------------------------------------------------------------- 1 | #resource block 2 | resource "aws_instance" "my_ec2" { 3 | ami = data.aws_ami.amzlinux2.id 4 | instance_type = var.my_instance_type 5 | key_name = var.my_key 6 | 7 | tags = { 8 | "Name" = "Ec2-Demo" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example1/provider.tf: -------------------------------------------------------------------------------- 1 | #terraform block 2 | terraform { 3 | required_version = "~> 1.0" 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" # Optional but recommended in production 8 | } 9 | } 10 | } 11 | 12 | 13 | #provider block 14 | provider "aws" { 15 | region = var.aws_region 16 | profile = "Landmark" 17 | } 18 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example1/variables.tf: -------------------------------------------------------------------------------- 1 | variable "aws_region"{ 2 | type = string 3 | default = "us-west-1" 4 | } 5 | 6 | variable "my_ami"{ 7 | type = string 8 | default = "ami-0e0bf4b3a0c0e0adc" 9 | } 10 | 11 | variable "my_instance_type"{ 12 | type = string 13 | default = "t2.medium" 14 | } 15 | 16 | variable "my_key"{ 17 | type = string 18 | default = "Automationkey" 19 | } 20 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example2/ami-datasource.tf: -------------------------------------------------------------------------------- 1 | # Get latest AMI ID for Amazon Linux2 OS 2 | data "aws_ami" "amzlinux2" { 3 | most_recent = true 4 | owners = ["amazon"] 5 | filter { 6 | name = "name" 7 | values = ["amzn2-ami-hvm-*-gp2"] 8 | } 9 | filter { 10 | name = "root-device-type" 11 | values = ["ebs"] 12 | } 13 | filter { 14 | name = "virtualization-type" 15 | values = ["hvm"] 16 | } 17 | filter { 18 | name = "architecture" 19 | values = ["x86_64"] 20 | } 21 | } -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example2/app1-install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Instance Identity Metadata Reference - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html 3 | sudo yum update -y 4 | sudo yum install -y httpd 5 | sudo systemctl enable httpd 6 | sudo service httpd start 7 | sudo echo '

Welcome to Landmark Technologies

' | sudo tee /var/www/html/index.html 8 | sudo mkdir /var/www/html/app1 9 | sudo echo '

Welcome to Landmark Technologies

Terraform Demo

Application Version: V1

' | sudo tee /var/www/html/app1/index.html 10 | sudo curl http://169.254.169.254/latest/dynamic/instance-identity/document -o /var/www/html/app1/metadata.html 11 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example2/ec2instance.tf: -------------------------------------------------------------------------------- 1 | # EC2 Instance 2 | resource "aws_instance" "myec2vm" { 3 | ami = data.aws_ami.amzlinux2.id 4 | instance_type = var.instance_type 5 | user_data = file("${path.module}/app1-install.sh") 6 | key_name = var.instance_keypair 7 | vpc_security_group_ids = [ aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id ] 8 | tags = { 9 | "Name" = "EC2 Demo 2" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example2/ec2securitygroups.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | 13 | egress { 14 | description = "Allow all ip and ports outbound" 15 | from_port = 0 16 | to_port = 0 17 | protocol = "-1" 18 | cidr_blocks = ["0.0.0.0/0"] 19 | } 20 | 21 | tags = { 22 | Name = "vpc-ssh" 23 | } 24 | } 25 | 26 | # Create Security Group - Web Traffic 27 | resource "aws_security_group" "vpc-web" { 28 | name = "vpc-web" 29 | description = "Dev VPC Web" 30 | ingress { 31 | description = "Allow Port 80" 32 | from_port = 80 33 | to_port = 80 34 | protocol = "tcp" 35 | cidr_blocks = ["0.0.0.0/0"] 36 | } 37 | ingress { 38 | description = "Allow Port 443" 39 | from_port = 443 40 | to_port = 443 41 | protocol = "tcp" 42 | cidr_blocks = ["0.0.0.0/0"] 43 | } 44 | egress { 45 | description = "Allow all ip and ports outbound" 46 | from_port = 0 47 | to_port = 0 48 | protocol = "-1" 49 | cidr_blocks = ["0.0.0.0/0"] 50 | } 51 | 52 | tags = { 53 | Name = "vpc-web" 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example2/outputs.tf: -------------------------------------------------------------------------------- 1 | # Terraform Output Values 2 | 3 | # EC2 Instance Public IP 4 | output "instance_publicip" { 5 | description = "EC2 Instance Public IP" 6 | value = aws_instance.myec2vm.public_ip 7 | } 8 | 9 | # EC2 Instance Public DNS 10 | output "instance_publicdns" { 11 | description = "EC2 Instance Public DNS" 12 | value = aws_instance.myec2vm.public_dns 13 | } 14 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example2/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | # AWS Region 3 | variable "aws_region" { 4 | description = "Region in which AWS Resources to be created" 5 | type = string 6 | default = "us-west-1" 7 | } 8 | 9 | # AWS EC2 Instance Type 10 | variable "instance_type" { 11 | description = "EC2 Instance Type" 12 | type = string 13 | default = "t2.micro" 14 | } 15 | 16 | # AWS EC2 Instance Key Pair 17 | variable "instance_keypair" { 18 | description = "AWS EC2 Key Pair that need to be associated with EC2 Instance" 19 | type = string 20 | default = "Automationkey" 21 | } 22 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/manifests/example2/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "Landmark" 16 | } 17 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/variable-files.md: -------------------------------------------------------------------------------- 1 | ## **Variable files** 2 | 3 | - Values for the input variables of a root module can be gathered in variable definition files and passed together using the -var-file=FILE option. 4 | 5 | - For all files which match terraform.tfvars or *.auto.tfvars present in the current directory, Terraform automatically loads them to populate variables. If the file is located somewhere else, you can pass the path to the file using the -var-file flag. It is recommended to name such files with names ending in .tfvars. 6 | 7 | - The -var-file flag can be used multiple times per command invocation: 8 | 9 | $ terraform apply -var-file=foo.tfvars -var-file=bar.tfvars 10 | 11 | - According to the terraform documentation on input variables, Terraform loads variables in the following order, with later sources taking precedence over earlier ones: 12 | 13 | - Environment variables 14 | - The tfvarsfile, if present. 15 | - The tfvars.jsonfile, if present. 16 | - Any *.auto.tfvars or *.auto.tfvars.json files, processed in lexical order of their filenames. 17 | Any -var and -var-file options on the command line, in order they are provided. (This includes variables set by a Terraform Cloud workspace.) 18 | 19 | # **Environmental variables** 20 | 21 | - When Terraform runs, it looks in your environment for variables that match the pattern TF_VAR_, and assigns those values to the corresponding Terraform variables in your configuration. 22 | - Assign values to the database administrator username and password using environment variables. 23 | 24 | $ export TF_VAR_db_username=admin TF_VAR_db_password=adifferentpassword 25 | 26 | # **.tfvars file** 27 | - Terraform supports setting variable values with variable definition (.tfvars) files. You can use multiple variable definition files, and many practitioners use a separate file to set sensitive or secret values. 28 | - Create a new file called secret.tfvars to assign values to the new variables. 29 | 30 | db_username = "admin" 31 | db_password = "insecurepassword" 32 | 33 | - Apply these changes using the -var-file parameter. Respond to the confirmation prompt with yes. 34 | 35 | $ terraform apply -var-file="secret.tfvars" 36 | -------------------------------------------------------------------------------- /05 - Variables and Data Sources/variable-types.md: -------------------------------------------------------------------------------- 1 | ## **Variables** 2 | 3 | - A variable is a value that can change, depending on conditions or on information passed to the program. 4 | - Variables are used to store information to be referenced and manipulated in a computer program. 5 | - They also provide a way of labeling data with a descriptive name, so our programs can be understood more clearly by the reader and ourselves. 6 | - It is helpful to think of variables as containers that hold information. Their sole purpose is to label and store data in memory. This data can then be used throughout your program. 7 | 8 | The following example shows the variable types that are supported by terraform. 9 | 10 | #**String** 11 | - Strings are usually represented by a double-quoted sequence of Unicode characters, "like this" 12 | ```t 13 | variable "vpcname" { 14 | type = string 15 | default = "myvpc" 16 | } 17 | 18 | ``` 19 | #**Number** 20 | 21 | - Numbers are represented by unquoted sequences of digits with or without a decimal point, like 15 or 6.283185. 22 | ```t 23 | variable "sshport" { 24 | type = number 25 | default = 22 26 | } 27 | ``` 28 | 29 | #**Boolean** 30 | - Bools are represented by the unquoted symbols true and false. 31 | ```t 32 | variable "enabled" { 33 | default = false 34 | } 35 | ``` 36 | #**List** 37 | - Lists is represented by a pair of square brackets containing a comma-separated sequence of values, like ["a", 15, true]. 38 | ```t 39 | variable "mylist" { 40 | type = list(string) 41 | default = ["Value1", "Value2"] 42 | } 43 | ``` 44 | #How to reference List values ? 45 | 46 | instance_type = var.mylist[1] 47 | 48 | #**Map** 49 | - Maps/objects are represented by a pair of curly braces containing a series of = pairs: 50 | ```T 51 | variable "mymap" { 52 | type = map 53 | default = { 54 | Key1 = "Value1" 55 | Key2 = "Value2" 56 | } 57 | } 58 | ``` 59 | #How to reference Map values ? 60 | 61 | instance_type = var.mymap["key1"] 62 | 63 | #**Input** 64 | ```t 65 | variable "inputname" { 66 | type = string 67 | description = "Set the name of the VPC" 68 | } 69 | ``` 70 | - note that if no default value is provided, then the variable will be an input variable and will prompt you to enter a value at runtime. 71 | 72 | ```t 73 | resource "aws_vpc" "myvpc" { 74 | cidr_block = "10.0.0.0/16" 75 | 76 | tags = { 77 | Name = var.inputname 78 | } 79 | } 80 | ``` 81 | #**Output** 82 | ```t 83 | output "vpcid" { 84 | value = aws_vpc.myvpc.id 85 | } 86 | ``` 87 | #**Tuple** 88 | - Lists/tuples are represented by a pair of square brackets containing a comma-separated sequence of values, like ["a", 15, true]. 89 | ```t 90 | variable "mytuple" { 91 | type = tuple([string, number, string]) 92 | default = ["cat", 1, "dog"] 93 | } 94 | ``` 95 | #**Objects** 96 | ```t 97 | variable "myobject" { 98 | type = object({ name = string, port = list(number) }) 99 | default = { 100 | name = "Landmark" 101 | port = [22, 25, 80] 102 | } 103 | } 104 | ``` 105 | #**Variables with Lists and Maps** 106 | 107 | #AWS EC2 Instance Type - List 108 | ```t 109 | variable "instance_type_list" { 110 | description = "EC2 Instance Type" 111 | type = list(string) 112 | default = ["t3.micro", "t3.small"] 113 | } 114 | 115 | #instance_type = var.instance_type_list[0] 116 | ``` 117 | 118 | #AWS EC2 Instance Type - Map 119 | ```t 120 | variable "instance_type_map" { 121 | description = "EC2 Instance Type" 122 | type = map(string) 123 | default = { 124 | "dev" = "t3.micro" 125 | "qa" = "t3.small" 126 | "prod" = "t3.large" 127 | } 128 | } 129 | 130 | #instance_type = var.instance_type_map["qa"] 131 | ``` 132 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/Dynamic blocks/ami-datasource.tf: -------------------------------------------------------------------------------- 1 | # Get latest AMI ID for Amazon Linux2 OS 2 | data "aws_ami" "amzlinux2" { 3 | most_recent = true 4 | owners = ["amazon"] 5 | filter { 6 | name = "name" 7 | values = ["amzn2-ami-hvm-*-gp2"] 8 | } 9 | filter { 10 | name = "root-device-type" 11 | values = ["ebs"] 12 | } 13 | filter { 14 | name = "virtualization-type" 15 | values = ["hvm"] 16 | } 17 | filter { 18 | name = "architecture" 19 | values = ["x86_64"] 20 | } 21 | } -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/Dynamic blocks/ec2.tf: -------------------------------------------------------------------------------- 1 | resource "aws_instance" "ec2" { 2 | ami = data.aws_ami.amzlinux2.id 3 | instance_type = var.my_instance_type 4 | security_groups = [aws_security_group.web-traffic.name] 5 | 6 | tags = { 7 | "Name" = "Prod_ec2" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/Dynamic blocks/main.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = "us-west-1" 15 | profile = "Kenmak" 16 | } 17 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/Dynamic blocks/sg.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "web-traffic" { 2 | name = "Allow HTTPS" 3 | 4 | dynamic "ingress" { 5 | iterator = port 6 | for_each = var.ingressrules 7 | content { 8 | from_port = port.value 9 | to_port = port.value 10 | protocol = "TCP" 11 | cidr_blocks = ["0.0.0.0/0"] 12 | } 13 | } 14 | 15 | dynamic "egress" { 16 | iterator = port 17 | for_each = var.egressrules 18 | content { 19 | from_port = port.value 20 | to_port = port.value 21 | protocol = "TCP" 22 | cidr_blocks = ["0.0.0.0/0"] 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/Dynamic blocks/variables.tf: -------------------------------------------------------------------------------- 1 | variable "ingressrules" { 2 | type = list(number) 3 | default = [80,443,8080] 4 | } 5 | 6 | variable "egressrules" { 7 | type = list(number) 8 | default = [80,443,25,3306,53,8080] 9 | } 10 | 11 | variable "my_instance_type"{ 12 | type = string 13 | default = "t2.micro" 14 | } 15 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/README.md: -------------------------------------------------------------------------------- 1 | # Terraform For Loops, Lists, Maps and Count Meta-Argument 2 | 3 | ## Step-00: Pre-requisite Note 4 | - We are using the `default vpc` in `us-west-2` region 5 | 6 | ## Step-01: Introduction 7 | - Terraform Meta-Argument: `Count` 8 | - **Terraform Lists & Maps** 9 | - List(string) 10 | - map(string) 11 | - **Terraform for loops** 12 | - for loop with List 13 | - for loop with Map 14 | - for loop with Map Advanced 15 | - **Splat Operators** 16 | - Legacy Splat Operator `.*.` 17 | - Generalized Splat Operator (latest) 18 | - Understand about Terraform Generic Splat Expression `[*]` when dealing with `count` Meta-Argument and multiple output values 19 | 20 | 21 | 22 | ## Step-02: variables.tf - Lists and Maps 23 | ```t 24 | # AWS EC2 Instance Type - List 25 | variable "instance_type_list" { 26 | description = "EC2 Instance Type" 27 | type = list(string) 28 | default = ["t3.micro", "t3.small"] 29 | } 30 | 31 | 32 | # AWS EC2 Instance Type - Map 33 | variable "instance_type_map" { 34 | description = "EC2 Instance Type" 35 | type = map(string) 36 | default = { 37 | "dev" = "t3.micro" 38 | "qa" = "t3.small" 39 | "prod" = "t3.large" 40 | } 41 | } 42 | ``` 43 | 44 | ## Step-04: ec2securitygroups.tf and ami-datasource.tf 45 | - No changes to both files 46 | 47 | ## Step-05: ec2instance.tf 48 | ```t 49 | # How to reference List values ? 50 | instance_type = var.instance_type_list[1] 51 | 52 | # How to reference Map values ? 53 | instance_type = var.instance_type_map["prod"] 54 | 55 | # Meta-Argument Count 56 | count = 2 57 | 58 | # count.index 59 | tags = { 60 | "Name" = "Count-Demo-${count.index}" 61 | } 62 | ``` 63 | 64 | ## Step-06: outputs.tf 65 | - for loop with List 66 | - for loop with Map 67 | - for loop with Map Advanced 68 | ```t 69 | 70 | # Output - For Loop with List 71 | output "for_output_list" { 72 | description = "For Loop with List" 73 | value = [for instance in aws_instance.myec2vm: instance.public_dns ] 74 | } 75 | 76 | # Output - For Loop with Map 77 | output "for_output_map1" { 78 | description = "For Loop with Map" 79 | value = {for instance in aws_instance.myec2vm: instance.id => instance.public_dns} 80 | } 81 | 82 | # Output - For Loop with Map Advanced 83 | output "for_output_map2" { 84 | description = "For Loop with Map - Advanced" 85 | value = {for c, instance in aws_instance.myec2vm: c => instance.public_dns} 86 | } 87 | 88 | # Output Legacy Splat Operator (latest) - Returns the List 89 | output "legacy_splat_instance_publicdns" { 90 | description = "Legacy Splat Expression" 91 | value = aws_instance.myec2vm.*.public_dns 92 | } 93 | 94 | # Output Latest Generalized Splat Operator - Returns the List 95 | output "latest_splat_instance_publicdns" { 96 | description = "Generalized Splat Expression" 97 | value = aws_instance.myec2vm[*].public_dns 98 | } 99 | ``` 100 | 101 | ## Step-07: Execute Terraform Commands 102 | ```t 103 | # Terraform Initialize 104 | terraform init 105 | 106 | # Terraform Validate 107 | terraform validate 108 | 109 | # Terraform Plan 110 | terraform plan 111 | Observations: 112 | 1) play with Lists and Maps for instance_type 113 | 114 | # Terraform Apply 115 | terraform apply -auto-approve 116 | Observations: 117 | 1) Two EC2 Instances (Count = 2) of a Resource myec2vm will be created 118 | 2) Count.index will start from 0 and end with 1 for VM Names 119 | 3) Review outputs in detail (for loop with list, maps, maps advanced, splat legacy and splat latest) 120 | ``` 121 | 122 | ## Step-08: Terraform Comments 123 | - Single Line Comments - `#` and `//` 124 | - Multi-line Commnets - `Start with /*` and `end with */` 125 | - We are going to comment the legacy splat operator, which might be decommissioned in future versions 126 | ```t 127 | # Output Legacy Splat Operator (latest) - Returns the List 128 | /* output "legacy_splat_instance_publicdns" { 129 | description = "Legacy Splat Expression" 130 | value = aws_instance.myec2vm.*.public_dns 131 | } */ 132 | ``` 133 | 134 | ## Step-09: Clean-Up 135 | ```t 136 | # Terraform Destroy 137 | terraform destroy -auto-approve 138 | 139 | # Files 140 | rm -rf .terraform* 141 | rm -rf terraform.tfstate* 142 | ``` 143 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/manifests/ami-datasource.tf: -------------------------------------------------------------------------------- 1 | # Get latest AMI ID for Amazon Linux2 OS 2 | data "aws_ami" "amzlinux2" { 3 | most_recent = true 4 | owners = ["amazon"] 5 | filter { 6 | name = "name" 7 | values = ["amzn2-ami-hvm-*-gp2"] 8 | } 9 | filter { 10 | name = "root-device-type" 11 | values = ["ebs"] 12 | } 13 | filter { 14 | name = "virtualization-type" 15 | values = ["hvm"] 16 | } 17 | filter { 18 | name = "architecture" 19 | values = ["x86_64"] 20 | } 21 | } -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/manifests/app1-install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Instance Identity Metadata Reference - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html 3 | sudo yum update -y 4 | sudo yum install -y httpd 5 | sudo systemctl enable httpd 6 | sudo service httpd start 7 | sudo echo '

Welcome to Landmark Technologies - APP-1

' | sudo tee /var/www/html/index.html 8 | sudo mkdir /var/www/html/app1 9 | sudo echo '

Welcome to Landmark Technologies

Terraform Demo

Application Version: V1

' | sudo tee /var/www/html/app1/index.html 10 | sudo curl http://169.254.169.254/latest/dynamic/instance-identity/document -o /var/www/html/app1/metadata.html 11 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/manifests/ec2instance.tf: -------------------------------------------------------------------------------- 1 | # EC2 Instance 2 | resource "aws_instance" "myec2" { 3 | ami = data.aws_ami.amzlinux2.id 4 | #instance_type = var.instance_type 5 | instance_type = var.instance_type_list[0] # For List 6 | #instance_type = var.instance_type_map["dev"] # For Map 7 | user_data = file("${path.module}/app1-install.sh") 8 | key_name = var.instance_keypair 9 | vpc_security_group_ids = [ aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id ] 10 | count = 1 11 | tags = { 12 | "Name" = "Prod-${count.index}" 13 | } 14 | } 15 | 16 | /* 17 | # Drawbacks of using count in this example 18 | - Resource Instances in this case were identified using index numbers 19 | instead of string values like actual subnet_id 20 | - If an element was removed from the middle of the list, 21 | every instance after that element would see its subnet_id value 22 | change, resulting in more remote object changes than intended. 23 | - Even the subnet_ids should be pre-defined or we need to get them again 24 | using for_each or for using various datasources 25 | - Using for_each gives the same flexibility without the extra churn. 26 | */ 27 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/manifests/ec2securitygroups.tf: -------------------------------------------------------------------------------- 1 | # Create Security Group - SSH Traffic 2 | resource "aws_security_group" "vpc-ssh" { 3 | name = "vpc-ssh" 4 | description = "Dev VPC SSH" 5 | ingress { 6 | description = "Allow Port 22" 7 | from_port = 22 8 | to_port = 22 9 | protocol = "tcp" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | 13 | egress { 14 | description = "Allow all ip and ports outbound" 15 | from_port = 0 16 | to_port = 0 17 | protocol = "-1" 18 | cidr_blocks = ["0.0.0.0/0"] 19 | } 20 | 21 | tags = { 22 | Name = "vpc-ssh" 23 | } 24 | } 25 | 26 | # Create Security Group - Web Traffic 27 | resource "aws_security_group" "vpc-web" { 28 | name = "vpc-web" 29 | description = "Dev VPC Web" 30 | ingress { 31 | description = "Allow Port 80" 32 | from_port = 80 33 | to_port = 80 34 | protocol = "tcp" 35 | cidr_blocks = ["0.0.0.0/0"] 36 | } 37 | ingress { 38 | description = "Allow Port 443" 39 | from_port = 443 40 | to_port = 443 41 | protocol = "tcp" 42 | cidr_blocks = ["0.0.0.0/0"] 43 | } 44 | egress { 45 | description = "Allow all ip and ports outbound" 46 | from_port = 0 47 | to_port = 0 48 | protocol = "-1" 49 | cidr_blocks = ["0.0.0.0/0"] 50 | } 51 | 52 | tags = { 53 | Name = "vpc-web" 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/manifests/outputs.tf: -------------------------------------------------------------------------------- 1 | # Terraform Output Values 2 | /* Concepts Covered 3 | 1. For Loop with List 4 | 2. For Loop with Map 5 | 3. For Loop with Map Advanced 6 | 4. Legacy Splat Operator (latest) - Returns List 7 | 5. Latest Generalized Splat Operator - Returns the List 8 | */ 9 | 10 | # Output - For Loop with List 11 | output "for_output_list" { 12 | description = "For Loop with List" 13 | value = [for instance in aws_instance.myec2: instance.public_dns] 14 | } 15 | 16 | # Output - For Loop with Map 17 | output "for_output_map1" { 18 | description = "For Loop with Map" 19 | value = {for instance in aws_instance.myec2: instance.id => instance.public_dns} 20 | } 21 | 22 | # Output - For Loop with Map Advanced 23 | output "for_output_map2" { 24 | description = "For Loop with Map - Advanced" 25 | value = {for c, instance in aws_instance.myec2: c => instance.public_dns} 26 | } 27 | 28 | # Output Legacy Splat Operator (Legacy) - Returns the List 29 | /* 30 | output "legacy_splat_instance_publicdns" { 31 | description = "Legacy Splat Operator" 32 | value = aws_instance.myec2.*.public_dns 33 | } 34 | */ 35 | 36 | # Output Latest Generalized Splat Operator - Returns the List 37 | output "latest_splat_instance_publicdns" { 38 | description = "Generalized latest Splat Operator" 39 | value = aws_instance.myec2[*].public_dns 40 | } 41 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/manifests/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | # AWS Region 3 | variable "aws_region" { 4 | description = "Region in which AWS Resources to be created" 5 | type = string 6 | default = "us-west-1" 7 | } 8 | 9 | # AWS EC2 Instance Type 10 | variable "instance_type" { 11 | description = "EC2 Instnace Type" 12 | type = string 13 | default = "t3.micro" 14 | } 15 | 16 | # AWS EC2 Instance Key Pair 17 | variable "instance_keypair" { 18 | description = "AWS EC2 Key Pair that need to be associated with EC2 Instance" 19 | type = string 20 | default = "Automationkey" 21 | } 22 | 23 | # AWS EC2 Instance Type - List 24 | variable "instance_type_list" { 25 | description = "EC2 Instance Type" 26 | type = list(string) 27 | default = ["t2.micro", "t2.medium", "t3.large"] 28 | } 29 | 30 | # AWS EC2 Instance Type - Map 31 | variable "instance_type_map" { 32 | description = "EC2 Instance Type" 33 | type = map(string) 34 | default = { 35 | "dev" = "t3.micro" 36 | "qa" = "t3.small" 37 | "prod" = "t3.large" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /06 - Meta Arguments-count, loops, lists, maps/manifests/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "Kenmak" 16 | } 17 | -------------------------------------------------------------------------------- /07 - Modules/example1-ec2/ec2/ami-datasource.tf: -------------------------------------------------------------------------------- 1 | # Get latest AMI ID for Amazon Linux2 OS 2 | data "aws_ami" "amzlinux2" { 3 | most_recent = true 4 | owners = ["amazon"] 5 | filter { 6 | name = "name" 7 | values = ["amzn2-ami-hvm-*-gp2"] 8 | } 9 | filter { 10 | name = "root-device-type" 11 | values = ["ebs"] 12 | } 13 | filter { 14 | name = "virtualization-type" 15 | values = ["hvm"] 16 | } 17 | filter { 18 | name = "architecture" 19 | values = ["x86_64"] 20 | } 21 | } -------------------------------------------------------------------------------- /07 - Modules/example1-ec2/ec2/ec2.tf: -------------------------------------------------------------------------------- 1 | 2 | resource "aws_instance" "ec2" { 3 | ami = data.aws_ami.amzlinux2.id 4 | instance_type = var.inst_type 5 | tags = { 6 | Name = var.ec2name 7 | } 8 | } 9 | 10 | output "instance_id" { 11 | value = aws_instance.ec2.id 12 | } 13 | -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/db/ami-datasource.tf: -------------------------------------------------------------------------------- 1 | # Get latest AMI ID for Amazon Linux2 OS 2 | data "aws_ami" "amzlinux2" { 3 | most_recent = true 4 | owners = ["amazon"] 5 | filter { 6 | name = "name" 7 | values = ["amzn2-ami-hvm-*-gp2"] 8 | } 9 | filter { 10 | name = "root-device-type" 11 | values = ["ebs"] 12 | } 13 | filter { 14 | name = "virtualization-type" 15 | values = ["hvm"] 16 | } 17 | filter { 18 | name = "architecture" 19 | values = ["x86_64"] 20 | } 21 | } -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/db/db.tf: -------------------------------------------------------------------------------- 1 | resource "aws_instance" "db" { 2 | ami = data.aws_ami.amzlinux2.id 3 | instance_type = "t2.micro" 4 | 5 | tags = { 6 | Name = "DB Server" 7 | } 8 | } 9 | 10 | output "PrivateIP" { 11 | value = aws_instance.db.private_ip 12 | } 13 | -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/eip/eip.tf: -------------------------------------------------------------------------------- 1 | variable "instance_id" { 2 | type = string 3 | } 4 | 5 | resource "aws_eip" "web_ip" { 6 | instance = var.instance_id 7 | } 8 | 9 | output "PublicIP" { 10 | value = aws_eip.web_ip.public_ip 11 | } 12 | -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/main.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | # Provider Block 12 | provider "aws" { 13 | region = "us-west-1" 14 | profile = "Kenmak" 15 | } 16 | 17 | module "db" { 18 | source = "./db" 19 | 20 | } 21 | 22 | module "web" { 23 | source = "./web" 24 | } 25 | 26 | output "PrivateIP" { 27 | value = module.db.PrivateIP 28 | } 29 | 30 | output "PublicIP" { 31 | value = module.web.pub_ip 32 | } 33 | -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/sg/sg.tf: -------------------------------------------------------------------------------- 1 | variable "ingress" { 2 | type = list(number) 3 | default = [80,443,8080] 4 | } 5 | 6 | variable "egress" { 7 | type = list(number) 8 | default = [80,443] 9 | } 10 | 11 | output "sg_name" { 12 | value = aws_security_group.web_traffic.name 13 | } 14 | 15 | resource "aws_security_group" "web_traffic" { 16 | name = "Allow Web Traffic" 17 | 18 | dynamic "ingress" { 19 | iterator = port 20 | for_each = var.ingress 21 | content { 22 | from_port = port.value 23 | to_port = port. value 24 | protocol = "TCP" 25 | cidr_blocks = ["0.0.0.0/0"] 26 | } 27 | } 28 | 29 | dynamic "egress" { 30 | iterator = port 31 | for_each = var.egress 32 | content { 33 | from_port = port.value 34 | to_port = port. value 35 | protocol = "TCP" 36 | cidr_blocks = ["0.0.0.0/0"] 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/terraform.tfstate: -------------------------------------------------------------------------------- 1 | { 2 | "version": 4, 3 | "terraform_version": "1.1.4", 4 | "serial": 12, 5 | "lineage": "62634f22-989f-0bc9-3086-04cd0bbd35a6", 6 | "outputs": {}, 7 | "resources": [] 8 | } 9 | -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/terraform.tfstate.backup: -------------------------------------------------------------------------------- 1 | { 2 | "version": 4, 3 | "terraform_version": "1.1.4", 4 | "serial": 5, 5 | "lineage": "62634f22-989f-0bc9-3086-04cd0bbd35a6", 6 | "outputs": { 7 | "PrivateIP": { 8 | "value": "172.31.14.43", 9 | "type": "string" 10 | }, 11 | "PublicIP": { 12 | "value": "54.219.38.11", 13 | "type": "string" 14 | } 15 | }, 16 | "resources": [ 17 | { 18 | "module": "module.db", 19 | "mode": "data", 20 | "type": "aws_ami", 21 | "name": "amzlinux2", 22 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 23 | "instances": [ 24 | { 25 | "schema_version": 0, 26 | "attributes": { 27 | "architecture": "x86_64", 28 | "arn": "arn:aws:ec2:us-west-1::image/ami-0ff7fc535d3457221", 29 | "block_device_mappings": [ 30 | { 31 | "device_name": "/dev/xvda", 32 | "ebs": { 33 | "delete_on_termination": "true", 34 | "encrypted": "false", 35 | "iops": "0", 36 | "snapshot_id": "snap-006494724b08ed045", 37 | "throughput": "0", 38 | "volume_size": "8", 39 | "volume_type": "gp2" 40 | }, 41 | "no_device": "", 42 | "virtual_name": "" 43 | } 44 | ], 45 | "creation_date": "2022-01-25T05:40:13.000Z", 46 | "description": "Amazon Linux 2 AMI 2.0.20220121.0 x86_64 HVM gp2", 47 | "ena_support": true, 48 | "executable_users": null, 49 | "filter": [ 50 | { 51 | "name": "architecture", 52 | "values": [ 53 | "x86_64" 54 | ] 55 | }, 56 | { 57 | "name": "name", 58 | "values": [ 59 | "amzn2-ami-hvm-*-gp2" 60 | ] 61 | }, 62 | { 63 | "name": "root-device-type", 64 | "values": [ 65 | "ebs" 66 | ] 67 | }, 68 | { 69 | "name": "virtualization-type", 70 | "values": [ 71 | "hvm" 72 | ] 73 | } 74 | ], 75 | "hypervisor": "xen", 76 | "id": "ami-0ff7fc535d3457221", 77 | "image_id": "ami-0ff7fc535d3457221", 78 | "image_location": "amazon/amzn2-ami-hvm-2.0.20220121.0-x86_64-gp2", 79 | "image_owner_alias": "amazon", 80 | "image_type": "machine", 81 | "kernel_id": null, 82 | "most_recent": true, 83 | "name": "amzn2-ami-hvm-2.0.20220121.0-x86_64-gp2", 84 | "name_regex": null, 85 | "owner_id": "137112412989", 86 | "owners": [ 87 | "amazon" 88 | ], 89 | "platform": null, 90 | "platform_details": "Linux/UNIX", 91 | "product_codes": [], 92 | "public": true, 93 | "ramdisk_id": null, 94 | "root_device_name": "/dev/xvda", 95 | "root_device_type": "ebs", 96 | "root_snapshot_id": "snap-006494724b08ed045", 97 | "sriov_net_support": "simple", 98 | "state": "available", 99 | "state_reason": { 100 | "code": "UNSET", 101 | "message": "UNSET" 102 | }, 103 | "tags": {}, 104 | "usage_operation": "RunInstances", 105 | "virtualization_type": "hvm" 106 | }, 107 | "sensitive_attributes": [] 108 | } 109 | ] 110 | }, 111 | { 112 | "module": "module.db", 113 | "mode": "managed", 114 | "type": "aws_instance", 115 | "name": "db", 116 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 117 | "instances": [ 118 | { 119 | "schema_version": 1, 120 | "attributes": { 121 | "ami": "ami-0ff7fc535d3457221", 122 | "arn": "arn:aws:ec2:us-west-1:411854276167:instance/i-015ecd41460186db0", 123 | "associate_public_ip_address": true, 124 | "availability_zone": "us-west-1c", 125 | "capacity_reservation_specification": [ 126 | { 127 | "capacity_reservation_preference": "open", 128 | "capacity_reservation_target": [] 129 | } 130 | ], 131 | "cpu_core_count": 1, 132 | "cpu_threads_per_core": 1, 133 | "credit_specification": [ 134 | { 135 | "cpu_credits": "standard" 136 | } 137 | ], 138 | "disable_api_termination": false, 139 | "ebs_block_device": [], 140 | "ebs_optimized": false, 141 | "enclave_options": [ 142 | { 143 | "enabled": false 144 | } 145 | ], 146 | "ephemeral_block_device": [], 147 | "get_password_data": false, 148 | "hibernation": false, 149 | "host_id": null, 150 | "iam_instance_profile": "", 151 | "id": "i-015ecd41460186db0", 152 | "instance_initiated_shutdown_behavior": "stop", 153 | "instance_state": "running", 154 | "instance_type": "t2.micro", 155 | "ipv6_address_count": 0, 156 | "ipv6_addresses": [], 157 | "key_name": "", 158 | "launch_template": [], 159 | "metadata_options": [ 160 | { 161 | "http_endpoint": "enabled", 162 | "http_put_response_hop_limit": 1, 163 | "http_tokens": "optional", 164 | "instance_metadata_tags": "disabled" 165 | } 166 | ], 167 | "monitoring": false, 168 | "network_interface": [], 169 | "outpost_arn": "", 170 | "password_data": "", 171 | "placement_group": "", 172 | "placement_partition_number": null, 173 | "primary_network_interface_id": "eni-0e92a1b33baccfa4f", 174 | "private_dns": "ip-172-31-14-43.us-west-1.compute.internal", 175 | "private_ip": "172.31.14.43", 176 | "public_dns": "ec2-54-153-57-118.us-west-1.compute.amazonaws.com", 177 | "public_ip": "54.153.57.118", 178 | "root_block_device": [ 179 | { 180 | "delete_on_termination": true, 181 | "device_name": "/dev/xvda", 182 | "encrypted": false, 183 | "iops": 100, 184 | "kms_key_id": "", 185 | "tags": {}, 186 | "throughput": 0, 187 | "volume_id": "vol-00ff670979657ae88", 188 | "volume_size": 8, 189 | "volume_type": "gp2" 190 | } 191 | ], 192 | "secondary_private_ips": [], 193 | "security_groups": [ 194 | "default" 195 | ], 196 | "source_dest_check": true, 197 | "subnet_id": "subnet-074b9d5d", 198 | "tags": { 199 | "Name": "DB Server" 200 | }, 201 | "tags_all": { 202 | "Name": "DB Server" 203 | }, 204 | "tenancy": "default", 205 | "timeouts": null, 206 | "user_data": null, 207 | "user_data_base64": null, 208 | "volume_tags": null, 209 | "vpc_security_group_ids": [ 210 | "sg-7d59470b" 211 | ] 212 | }, 213 | "sensitive_attributes": [], 214 | "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTIwMDAwMDAwMDAwMCwidXBkYXRlIjo2MDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", 215 | "dependencies": [ 216 | "module.db.data.aws_ami.amzlinux2" 217 | ] 218 | } 219 | ] 220 | }, 221 | { 222 | "module": "module.web", 223 | "mode": "data", 224 | "type": "aws_ami", 225 | "name": "amzlinux2", 226 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 227 | "instances": [ 228 | { 229 | "schema_version": 0, 230 | "attributes": { 231 | "architecture": "x86_64", 232 | "arn": "arn:aws:ec2:us-west-1::image/ami-0ff7fc535d3457221", 233 | "block_device_mappings": [ 234 | { 235 | "device_name": "/dev/xvda", 236 | "ebs": { 237 | "delete_on_termination": "true", 238 | "encrypted": "false", 239 | "iops": "0", 240 | "snapshot_id": "snap-006494724b08ed045", 241 | "throughput": "0", 242 | "volume_size": "8", 243 | "volume_type": "gp2" 244 | }, 245 | "no_device": "", 246 | "virtual_name": "" 247 | } 248 | ], 249 | "creation_date": "2022-01-25T05:40:13.000Z", 250 | "description": "Amazon Linux 2 AMI 2.0.20220121.0 x86_64 HVM gp2", 251 | "ena_support": true, 252 | "executable_users": null, 253 | "filter": [ 254 | { 255 | "name": "architecture", 256 | "values": [ 257 | "x86_64" 258 | ] 259 | }, 260 | { 261 | "name": "name", 262 | "values": [ 263 | "amzn2-ami-hvm-*-gp2" 264 | ] 265 | }, 266 | { 267 | "name": "root-device-type", 268 | "values": [ 269 | "ebs" 270 | ] 271 | }, 272 | { 273 | "name": "virtualization-type", 274 | "values": [ 275 | "hvm" 276 | ] 277 | } 278 | ], 279 | "hypervisor": "xen", 280 | "id": "ami-0ff7fc535d3457221", 281 | "image_id": "ami-0ff7fc535d3457221", 282 | "image_location": "amazon/amzn2-ami-hvm-2.0.20220121.0-x86_64-gp2", 283 | "image_owner_alias": "amazon", 284 | "image_type": "machine", 285 | "kernel_id": null, 286 | "most_recent": true, 287 | "name": "amzn2-ami-hvm-2.0.20220121.0-x86_64-gp2", 288 | "name_regex": null, 289 | "owner_id": "137112412989", 290 | "owners": [ 291 | "amazon" 292 | ], 293 | "platform": null, 294 | "platform_details": "Linux/UNIX", 295 | "product_codes": [], 296 | "public": true, 297 | "ramdisk_id": null, 298 | "root_device_name": "/dev/xvda", 299 | "root_device_type": "ebs", 300 | "root_snapshot_id": "snap-006494724b08ed045", 301 | "sriov_net_support": "simple", 302 | "state": "available", 303 | "state_reason": { 304 | "code": "UNSET", 305 | "message": "UNSET" 306 | }, 307 | "tags": {}, 308 | "usage_operation": "RunInstances", 309 | "virtualization_type": "hvm" 310 | }, 311 | "sensitive_attributes": [] 312 | } 313 | ] 314 | }, 315 | { 316 | "module": "module.web", 317 | "mode": "managed", 318 | "type": "aws_instance", 319 | "name": "web", 320 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 321 | "instances": [ 322 | { 323 | "schema_version": 1, 324 | "attributes": { 325 | "ami": "ami-0ff7fc535d3457221", 326 | "arn": "arn:aws:ec2:us-west-1:411854276167:instance/i-0fe4f241f312fd4bc", 327 | "associate_public_ip_address": true, 328 | "availability_zone": "us-west-1c", 329 | "capacity_reservation_specification": [ 330 | { 331 | "capacity_reservation_preference": "open", 332 | "capacity_reservation_target": [] 333 | } 334 | ], 335 | "cpu_core_count": 1, 336 | "cpu_threads_per_core": 1, 337 | "credit_specification": [ 338 | { 339 | "cpu_credits": "standard" 340 | } 341 | ], 342 | "disable_api_termination": false, 343 | "ebs_block_device": [], 344 | "ebs_optimized": false, 345 | "enclave_options": [ 346 | { 347 | "enabled": false 348 | } 349 | ], 350 | "ephemeral_block_device": [], 351 | "get_password_data": false, 352 | "hibernation": false, 353 | "host_id": null, 354 | "iam_instance_profile": "", 355 | "id": "i-0fe4f241f312fd4bc", 356 | "instance_initiated_shutdown_behavior": "stop", 357 | "instance_state": "running", 358 | "instance_type": "t2.micro", 359 | "ipv6_address_count": 0, 360 | "ipv6_addresses": [], 361 | "key_name": "", 362 | "launch_template": [], 363 | "metadata_options": [ 364 | { 365 | "http_endpoint": "enabled", 366 | "http_put_response_hop_limit": 1, 367 | "http_tokens": "optional", 368 | "instance_metadata_tags": "disabled" 369 | } 370 | ], 371 | "monitoring": false, 372 | "network_interface": [], 373 | "outpost_arn": "", 374 | "password_data": "", 375 | "placement_group": "", 376 | "placement_partition_number": null, 377 | "primary_network_interface_id": "eni-00e6bfb1dd2bbea64", 378 | "private_dns": "ip-172-31-7-69.us-west-1.compute.internal", 379 | "private_ip": "172.31.7.69", 380 | "public_dns": "ec2-54-193-67-118.us-west-1.compute.amazonaws.com", 381 | "public_ip": "54.193.67.118", 382 | "root_block_device": [ 383 | { 384 | "delete_on_termination": true, 385 | "device_name": "/dev/xvda", 386 | "encrypted": false, 387 | "iops": 100, 388 | "kms_key_id": "", 389 | "tags": {}, 390 | "throughput": 0, 391 | "volume_id": "vol-06e7f4e63022bddc2", 392 | "volume_size": 8, 393 | "volume_type": "gp2" 394 | } 395 | ], 396 | "secondary_private_ips": [], 397 | "security_groups": [ 398 | "Allow Web Traffic" 399 | ], 400 | "source_dest_check": true, 401 | "subnet_id": "subnet-074b9d5d", 402 | "tags": { 403 | "Name": "Web Server" 404 | }, 405 | "tags_all": { 406 | "Name": "Web Server" 407 | }, 408 | "tenancy": "default", 409 | "timeouts": null, 410 | "user_data": "894b88d19005099458edf6380cf68c5a3e067710", 411 | "user_data_base64": null, 412 | "volume_tags": null, 413 | "vpc_security_group_ids": [ 414 | "sg-02ca7d8836df399fe" 415 | ] 416 | }, 417 | "sensitive_attributes": [], 418 | "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTIwMDAwMDAwMDAwMCwidXBkYXRlIjo2MDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", 419 | "dependencies": [ 420 | "module.web.data.aws_ami.amzlinux2", 421 | "module.web.module.sg.aws_security_group.web_traffic" 422 | ] 423 | } 424 | ] 425 | }, 426 | { 427 | "module": "module.web.module.eip", 428 | "mode": "managed", 429 | "type": "aws_eip", 430 | "name": "web_ip", 431 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 432 | "instances": [ 433 | { 434 | "schema_version": 0, 435 | "attributes": { 436 | "address": null, 437 | "allocation_id": "eipalloc-0e5b3adf4c1e2e5e0", 438 | "associate_with_private_ip": null, 439 | "association_id": "eipassoc-03972002faee5b7f7", 440 | "carrier_ip": "", 441 | "customer_owned_ip": "", 442 | "customer_owned_ipv4_pool": "", 443 | "domain": "vpc", 444 | "id": "eipalloc-0e5b3adf4c1e2e5e0", 445 | "instance": "i-0fe4f241f312fd4bc", 446 | "network_border_group": "us-west-1", 447 | "network_interface": "eni-00e6bfb1dd2bbea64", 448 | "private_dns": "ip-172-31-7-69.us-west-1.compute.internal", 449 | "private_ip": "172.31.7.69", 450 | "public_dns": "ec2-54-219-38-11.us-west-1.compute.amazonaws.com", 451 | "public_ip": "54.219.38.11", 452 | "public_ipv4_pool": "amazon", 453 | "tags": null, 454 | "tags_all": {}, 455 | "timeouts": null, 456 | "vpc": true 457 | }, 458 | "sensitive_attributes": [], 459 | "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiZGVsZXRlIjoxODAwMDAwMDAwMDAsInJlYWQiOjkwMDAwMDAwMDAwMCwidXBkYXRlIjozMDAwMDAwMDAwMDB9fQ==", 460 | "dependencies": [ 461 | "module.web.aws_instance.web", 462 | "module.web.data.aws_ami.amzlinux2", 463 | "module.web.module.sg.aws_security_group.web_traffic" 464 | ] 465 | } 466 | ] 467 | }, 468 | { 469 | "module": "module.web.module.sg", 470 | "mode": "managed", 471 | "type": "aws_security_group", 472 | "name": "web_traffic", 473 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 474 | "instances": [ 475 | { 476 | "schema_version": 1, 477 | "attributes": { 478 | "arn": "arn:aws:ec2:us-west-1:411854276167:security-group/sg-02ca7d8836df399fe", 479 | "description": "Managed by Terraform", 480 | "egress": [ 481 | { 482 | "cidr_blocks": [ 483 | "0.0.0.0/0" 484 | ], 485 | "description": "", 486 | "from_port": 443, 487 | "ipv6_cidr_blocks": [], 488 | "prefix_list_ids": [], 489 | "protocol": "tcp", 490 | "security_groups": [], 491 | "self": false, 492 | "to_port": 443 493 | }, 494 | { 495 | "cidr_blocks": [ 496 | "0.0.0.0/0" 497 | ], 498 | "description": "", 499 | "from_port": 80, 500 | "ipv6_cidr_blocks": [], 501 | "prefix_list_ids": [], 502 | "protocol": "tcp", 503 | "security_groups": [], 504 | "self": false, 505 | "to_port": 80 506 | } 507 | ], 508 | "id": "sg-02ca7d8836df399fe", 509 | "ingress": [ 510 | { 511 | "cidr_blocks": [ 512 | "0.0.0.0/0" 513 | ], 514 | "description": "", 515 | "from_port": 443, 516 | "ipv6_cidr_blocks": [], 517 | "prefix_list_ids": [], 518 | "protocol": "tcp", 519 | "security_groups": [], 520 | "self": false, 521 | "to_port": 443 522 | }, 523 | { 524 | "cidr_blocks": [ 525 | "0.0.0.0/0" 526 | ], 527 | "description": "", 528 | "from_port": 80, 529 | "ipv6_cidr_blocks": [], 530 | "prefix_list_ids": [], 531 | "protocol": "tcp", 532 | "security_groups": [], 533 | "self": false, 534 | "to_port": 80 535 | } 536 | ], 537 | "name": "Allow Web Traffic", 538 | "name_prefix": "", 539 | "owner_id": "411854276167", 540 | "revoke_rules_on_delete": false, 541 | "tags": null, 542 | "tags_all": {}, 543 | "timeouts": null, 544 | "vpc_id": "vpc-b1448fd7" 545 | }, 546 | "sensitive_attributes": [], 547 | "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6OTAwMDAwMDAwMDAwfSwic2NoZW1hX3ZlcnNpb24iOiIxIn0=" 548 | } 549 | ] 550 | } 551 | ] 552 | } 553 | -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/web/ami-datasource.tf: -------------------------------------------------------------------------------- 1 | # Get latest AMI ID for Amazon Linux2 OS 2 | data "aws_ami" "amzlinux2" { 3 | most_recent = true 4 | owners = ["amazon"] 5 | filter { 6 | name = "name" 7 | values = ["amzn2-ami-hvm-*-gp2"] 8 | } 9 | filter { 10 | name = "root-device-type" 11 | values = ["ebs"] 12 | } 13 | filter { 14 | name = "virtualization-type" 15 | values = ["hvm"] 16 | } 17 | filter { 18 | name = "architecture" 19 | values = ["x86_64"] 20 | } 21 | } -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/web/server-script.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Instance Identity Metadata Reference - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html 3 | sudo yum update -y 4 | sudo yum install -y httpd 5 | sudo systemctl enable httpd 6 | sudo service httpd start 7 | sudo echo '

Welcome to Landmark Technologies

' | sudo tee /var/www/html/index.html 8 | sudo mkdir /var/www/html/app1 9 | sudo echo '

Welcome to Landmark Technologies

Terraform Demo

Application Version: V1

' | sudo tee /var/www/html/app1/index.html 10 | sudo curl http://169.254.169.254/latest/dynamic/instance-identity/document -o /var/www/html/app1/metadata.html 11 | 12 | 13 | # Ensure that you update the inbound rules on the security group of your instance. Add http port 80 14 | -------------------------------------------------------------------------------- /07 - Modules/example2-db-web-eip-sg/web/web.tf: -------------------------------------------------------------------------------- 1 | resource "aws_instance" "web" { 2 | ami = data.aws_ami.amzlinux2.id 3 | instance_type = "t2.micro" 4 | security_groups = [module.sg.sg_name] 5 | user_data = file("./web/server-script.sh") 6 | tags = { 7 | Name = "Web Server" 8 | } 9 | } 10 | 11 | output "pub_ip" { 12 | value = module.eip.PublicIP 13 | } 14 | 15 | module "eip" { 16 | source = "../eip" 17 | instance_id = aws_instance.web.id 18 | } 19 | 20 | module "sg" { 21 | source = "../sg" 22 | } 23 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/README.md: -------------------------------------------------------------------------------- 1 | # Design a 3 Tier AWS VPC with NAT Gateways using Terraform 2 | 3 | ## Step-01: Introduction 4 | - Understand about Terraform Modules 5 | - Create VPC using `Terraform Modules` 6 | - Define `Input Variables` for VPC module and reference them in VPC Terraform Module 7 | - Define `local values` and reference them in VPC Terraform Module 8 | - Create `terraform.tfvars` to load variable values by default from this file 9 | - Create `vpc.auto.tfvars` to load variable values by default from this file related to a VPC 10 | - Define `Output Values` for VPC 11 | 12 | ## Step-02: v1-vpc-module - Hardcoded Model 13 | ### Step-02-01: How to make a decision of using the public Registry module? 14 | 1. Understand about [Terraform Registry and Modules](https://registry.terraform.io/) 15 | 2. We are going to use a [VPC Module](https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest) from Terraform Public Registry 16 | 3. Understand about Authenticity of a module hosted on Public Terraform Registry with [HashiCorp Verified Tag](https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest) 17 | 4. Review the download rate for that module 18 | 5. Review the latest versions and [release history](https://github.com/terraform-aws-modules/terraform-aws-vpc/releases) of that module 19 | 6. Review our feature needs when using that module and ensure if our need is satisfied use the module else use the standard terraform resource definition appraoch. 20 | 7. Review module inputs, outputs and dependencies too. 21 | ### Step-02-02: Create a VPC Module Terraform Configuration 22 | - c1-versions.tf 23 | - c2-generic-variables.tf 24 | - c3-vpc.tf 25 | - [Terraform AWS VPC Module](https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest) 26 | ```t 27 | # Create VPC Terraform Module 28 | module "vpc" { 29 | source = "terraform-aws-modules/vpc/aws" 30 | version = "2.78.0" 31 | 32 | # VPC Basic Details 33 | name = "vpc-dev" 34 | cidr = "10.0.0.0/16" 35 | azs = ["us-east-1a", "us-east-1b"] 36 | private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] 37 | public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] 38 | 39 | # Database Subnets 40 | create_database_subnet_group = true 41 | create_database_subnet_route_table= true 42 | database_subnets = ["10.0.151.0/24", "10.0.152.0/24"] 43 | 44 | #create_database_nat_gateway_route = true 45 | #create_database_internet_gateway_route = true 46 | 47 | # NAT Gateways - Outbound Communication 48 | enable_nat_gateway = true 49 | single_nat_gateway = true 50 | 51 | # VPC DNS Parameters 52 | enable_dns_hostnames = true 53 | enable_dns_support = true 54 | 55 | public_subnet_tags = { 56 | Type = "public-subnets" 57 | } 58 | 59 | private_subnet_tags = { 60 | Type = "private-subnets" 61 | } 62 | 63 | database_subnet_tags = { 64 | Type = "database-subnets" 65 | } 66 | 67 | tags = { 68 | Owner = "Landmark" 69 | Environment = "dev" 70 | } 71 | 72 | vpc_tags = { 73 | Name = "vpc-dev" 74 | } 75 | } 76 | ``` 77 | 78 | ## Step-03: Execute Terraform Commands 79 | ```t 80 | # Working Folder 81 | terraform-manifests/v1-vpc-module 82 | 83 | # Terraform Initialize 84 | terraform init 85 | Observation: 86 | 1. Verify if modules got downloaded to .terraform folder 87 | 88 | # Terraform Validate 89 | terraform validate 90 | 91 | # Terraform plan 92 | terraform plan 93 | 94 | # Terraform Apply 95 | terraform apply -auto-approve 96 | Observation: 97 | 1) Verify VPC 98 | 2) Verify Subnets 99 | 3) Verify IGW 100 | 4) Verify Public Route for Public Subnets 101 | 5) Verify no public route for private subnets 102 | 6) Verify NAT Gateway and Elastic IP for NAT Gateway 103 | 7) Verify NAT Gateway route for Private Subnets 104 | 8) Verify no public route or no NAT Gateway route to Database Subnets 105 | 9) Verify Tags 106 | 107 | # Terraform Destroy 108 | terraform destroy -auto-approve 109 | 110 | # Delete Files 111 | rm -rf .terraform* 112 | rm -rf terraform.tfstate* 113 | ``` 114 | 115 | ## Step-04: Version Constraints in Terraform with Modules 116 | - [Terraform Version Constraints](https://www.terraform.io/docs/language/expressions/version-constraints.html) 117 | - For modules locking to the exact version is recommended to ensure there will not be any major breakages in production 118 | - When depending on third-party modules, require specific versions to ensure that updates only happen when convenient to you 119 | - For modules maintained within your organization, specifying version ranges may be appropriate if semantic versioning is used consistently or if there is a well-defined release process that avoids unwanted updates. 120 | - [Review and understand this carefully](https://www.terraform.io/docs/language/expressions/version-constraints.html#terraform-core-and-provider-versions) 121 | 122 | ## Step-05: vpc-module-standardized - Standardized and Generalized 123 | - In the next series of steps we are going to standardize the VPC configuration 124 | - c2-generic-variables.tf 125 | ```t 126 | # Input Variables 127 | # AWS Region 128 | variable "aws_region" { 129 | description = "Region in which AWS Resources to be created" 130 | type = string 131 | default = "us-east-1" 132 | } 133 | # Environment Variable 134 | variable "environment" { 135 | description = "Environment Variable used as a prefix" 136 | type = string 137 | default = "dev" 138 | } 139 | # Business Division 140 | variable "business_divsion" { 141 | description = "Business Division in the large organization this Infrastructure belongs" 142 | type = string 143 | default = "HR" 144 | } 145 | ``` 146 | 147 | ## Step-06: local-values.tf 148 | - Understand about [Local Values](https://www.terraform.io/docs/language/values/locals.html) 149 | ```t 150 | # Define Local Values in Terraform 151 | locals { 152 | owners = var.business_divsion 153 | environment = var.environment 154 | name = "${var.business_divsion}-${var.environment}" 155 | common_tags = { 156 | owners = local.owners 157 | environment = local.environment 158 | } 159 | } 160 | ``` 161 | 162 | ## Step-07: c4-01-vpc-variables.tf 163 | ```t 164 | # VPC Input Variables 165 | 166 | # VPC Name 167 | variable "vpc_name" { 168 | description = "VPC Name" 169 | type = string 170 | default = "myvpc" 171 | } 172 | 173 | # VPC CIDR Block 174 | variable "vpc_cidr_block" { 175 | description = "VPC CIDR Block" 176 | type = string 177 | default = "10.0.0.0/16" 178 | } 179 | 180 | # VPC Availability Zones 181 | variable "vpc_availability_zones" { 182 | description = "VPC Availability Zones" 183 | type = list(string) 184 | default = ["us-east-1a", "us-east-1b"] 185 | } 186 | 187 | # VPC Public Subnets 188 | variable "vpc_public_subnets" { 189 | description = "VPC Public Subnets" 190 | type = list(string) 191 | default = ["10.0.101.0/24", "10.0.102.0/24"] 192 | } 193 | 194 | # VPC Private Subnets 195 | variable "vpc_private_subnets" { 196 | description = "VPC Private Subnets" 197 | type = list(string) 198 | default = ["10.0.1.0/24", "10.0.2.0/24"] 199 | } 200 | 201 | # VPC Database Subnets 202 | variable "vpc_database_subnets" { 203 | description = "VPC Database Subnets" 204 | type = list(string) 205 | default = ["10.0.151.0/24", "10.0.152.0/24"] 206 | } 207 | 208 | # VPC Create Database Subnet Group (True / False) 209 | variable "vpc_create_database_subnet_group" { 210 | description = "VPC Create Database Subnet Group" 211 | type = bool 212 | default = true 213 | } 214 | 215 | # VPC Create Database Subnet Route Table (True or False) 216 | variable "vpc_create_database_subnet_route_table" { 217 | description = "VPC Create Database Subnet Route Table" 218 | type = bool 219 | default = true 220 | } 221 | 222 | 223 | # VPC Enable NAT Gateway (True or False) 224 | variable "vpc_enable_nat_gateway" { 225 | description = "Enable NAT Gateways for Private Subnets Outbound Communication" 226 | type = bool 227 | default = true 228 | } 229 | 230 | # VPC Single NAT Gateway (True or False) 231 | variable "vpc_single_nat_gateway" { 232 | description = "Enable only single NAT Gateway in one Availability Zone to save costs during our demos" 233 | type = bool 234 | default = true 235 | } 236 | ``` 237 | ## Step-08: c4-02-vpc-module.tf 238 | ```t 239 | # Create VPC Terraform Module 240 | module "vpc" { 241 | source = "terraform-aws-modules/vpc/aws" 242 | version = "2.78.0" 243 | #version = "~> 2.0" 244 | 245 | # VPC Basic Details 246 | name = "${local.name}-${var.vpc_name}" 247 | cidr = var.vpc_cidr_block 248 | azs = var.vpc_availability_zones 249 | public_subnets = var.vpc_public_subnets 250 | private_subnets = var.vpc_private_subnets 251 | 252 | # Database Subnets 253 | database_subnets = var.vpc_database_subnets 254 | create_database_subnet_group = var.vpc_create_database_subnet_group 255 | create_database_subnet_route_table = var.vpc_create_database_subnet_route_table 256 | # create_database_internet_gateway_route = true 257 | # create_database_nat_gateway_route = true 258 | 259 | # NAT Gateways - Outbound Communication 260 | enable_nat_gateway = var.vpc_enable_nat_gateway 261 | single_nat_gateway = var.vpc_single_nat_gateway 262 | 263 | # VPC DNS Parameters 264 | enable_dns_hostnames = true 265 | enable_dns_support = true 266 | 267 | 268 | tags = local.common_tags 269 | vpc_tags = local.common_tags 270 | 271 | # Additional Tags to Subnets 272 | public_subnet_tags = { 273 | Type = "Public Subnets" 274 | } 275 | private_subnet_tags = { 276 | Type = "Private Subnets" 277 | } 278 | database_subnet_tags = { 279 | Type = "Private Database Subnets" 280 | } 281 | } 282 | ``` 283 | ## Step-09: c4-03-vpc-outputs.tf 284 | ```t 285 | # VPC Output Values 286 | 287 | # VPC ID 288 | output "vpc_id" { 289 | description = "The ID of the VPC" 290 | value = module.vpc.vpc_id 291 | } 292 | 293 | # VPC CIDR blocks 294 | output "vpc_cidr_block" { 295 | description = "The CIDR block of the VPC" 296 | value = module.vpc.vpc_cidr_block 297 | } 298 | 299 | # VPC Private Subnets 300 | output "private_subnets" { 301 | description = "List of IDs of private subnets" 302 | value = module.vpc.private_subnets 303 | } 304 | 305 | # VPC Public Subnets 306 | output "public_subnets" { 307 | description = "List of IDs of public subnets" 308 | value = module.vpc.public_subnets 309 | } 310 | 311 | # VPC NAT gateway Public IP 312 | output "nat_public_ips" { 313 | description = "List of public Elastic IPs created for AWS NAT Gateway" 314 | value = module.vpc.nat_public_ips 315 | } 316 | 317 | # VPC AZs 318 | output "azs" { 319 | description = "A list of availability zones spefified as argument to this module" 320 | value = module.vpc.azs 321 | } 322 | ``` 323 | ## Step-10: terraform.tfvars 324 | ```t 325 | # Generic Variables 326 | aws_region = "us-east-1" 327 | environment = "dev" 328 | business_divsion = "HR" 329 | ``` 330 | 331 | ## Step-11: vpc.auto.tfvars 332 | ```t 333 | # VPC Variables 334 | vpc_name = "myvpc" 335 | vpc_cidr_block = "10.0.0.0/16" 336 | vpc_availability_zones = ["us-east-1a", "us-east-1b"] 337 | vpc_public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] 338 | vpc_private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] 339 | vpc_database_subnets= ["10.0.151.0/24", "10.0.152.0/24"] 340 | vpc_create_database_subnet_group = true 341 | vpc_create_database_subnet_route_table = true 342 | vpc_enable_nat_gateway = true 343 | vpc_single_nat_gateway = true 344 | ``` 345 | 346 | 347 | ## Step-12: Execute Terraform Commands 348 | ```t 349 | # Working Folder 350 | terraform-manifests/v2-vpc-module-standardized 351 | 352 | # Terraform Initialize 353 | terraform init 354 | 355 | # Terraform Validate 356 | terraform validate 357 | 358 | # Terraform plan 359 | terraform plan 360 | 361 | # Terraform Apply 362 | terraform apply -auto-approve 363 | Observation: 364 | 1) Verify VPC 365 | 2) Verify Subnets 366 | 3) Verify IGW 367 | 4) Verify Public Route for Public Subnets 368 | 5) Verify no public route for private subnets 369 | 6) Verify NAT Gateway and Elastic IP for NAT Gateway 370 | 7) Verify NAT Gateway route for Private Subnets 371 | 8) Verify no public route or no NAT Gateway route to Database Subnets 372 | 9) Verify Tags 373 | ``` 374 | 375 | ## Step-13: Clean-Up 376 | ```t 377 | # Terraform Destroy 378 | terraform destroy -auto-approve 379 | 380 | # Delete Files 381 | rm -rf .terraform* 382 | rm -rf terraform.tfstate* 383 | ``` 384 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module-standardized/01-versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | /* 18 | Note-1: AWS Credentials Profile (profile = "default") configured on your local desktop terminal 19 | $HOME/.aws/credentials 20 | */ 21 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module-standardized/02-variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | # AWS Region 3 | variable "aws_region" { 4 | description = "Region in which AWS Resources to be created" 5 | type = string 6 | default = "us-west-2" 7 | } 8 | # Environment Variable 9 | variable "environment" { 10 | description = "Environment Variable used as a prefix" 11 | type = string 12 | default = "dev" 13 | } 14 | # Business Division 15 | variable "business_division" { 16 | description = "Business Division in the large organization this Infrastructure belongs" 17 | type = string 18 | default = "Finance" 19 | } 20 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module-standardized/03-local-values.tf: -------------------------------------------------------------------------------- 1 | # Define Local Values in Terraform 2 | locals { 3 | owners = var.business_division 4 | environment = var.environment 5 | name = "${var.business_division}-${var.environment}" 6 | #name = "${local.owners}-${local.environment}" 7 | common_tags = { 8 | owners = local.owners 9 | environment = local.environment 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module-standardized/04-vpc-variables.tf: -------------------------------------------------------------------------------- 1 | # VPC Input Variables 2 | 3 | # VPC Name 4 | variable "vpc_name" { 5 | description = "VPC Name" 6 | type = string 7 | default = "myvpc" 8 | } 9 | 10 | # VPC CIDR Block 11 | variable "vpc_cidr_block" { 12 | description = "VPC CIDR Block" 13 | type = string 14 | default = "10.0.0.0/16" 15 | } 16 | 17 | # VPC Availability Zones 18 | variable "vpc_availability_zones" { 19 | description = "VPC Availability Zones" 20 | type = list(string) 21 | default = ["us-west-1a", "us-west-1c"] 22 | } 23 | 24 | # VPC Public Subnets 25 | variable "vpc_public_subnets" { 26 | description = "VPC Public Subnets" 27 | type = list(string) 28 | default = ["10.0.101.0/24", "10.0.102.0/24"] 29 | } 30 | 31 | # VPC Private Subnets 32 | variable "vpc_private_subnets" { 33 | description = "VPC Private Subnets" 34 | type = list(string) 35 | default = ["10.0.1.0/24", "10.0.2.0/24"] 36 | } 37 | 38 | # VPC Database Subnets 39 | variable "vpc_database_subnets" { 40 | description = "VPC Database Subnets" 41 | type = list(string) 42 | default = ["10.0.151.0/24", "10.0.152.0/24"] 43 | } 44 | 45 | # VPC Create Database Subnet Group (True / False) 46 | variable "vpc_create_database_subnet_group" { 47 | description = "VPC Create Database Subnet Group" 48 | type = bool 49 | default = true 50 | } 51 | 52 | # VPC Create Database Subnet Route Table (True or False) 53 | variable "vpc_create_database_subnet_route_table" { 54 | description = "VPC Create Database Subnet Route Table" 55 | type = bool 56 | default = true 57 | } 58 | 59 | 60 | # VPC Enable NAT Gateway (True or False) 61 | variable "vpc_enable_nat_gateway" { 62 | description = "Enable NAT Gateways for Private Subnets Outbound Communication" 63 | type = bool 64 | default = true 65 | } 66 | 67 | # VPC Single NAT Gateway (True or False) 68 | variable "vpc_single_nat_gateway" { 69 | description = "Enable only single NAT Gateway in one Availability Zone to save costs during our demos" 70 | type = bool 71 | default = true 72 | } 73 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module-standardized/05-vpc-module.tf: -------------------------------------------------------------------------------- 1 | # Create VPC Terraform Module 2 | module "vpc" { 3 | source = "terraform-aws-modules/vpc/aws" 4 | version = "3.11.5" 5 | #version = "~> 2.78" 6 | 7 | # VPC Basic Details 8 | name = "${local.name}-${var.vpc_name}" 9 | cidr = var.vpc_cidr_block 10 | azs = var.vpc_availability_zones 11 | public_subnets = var.vpc_public_subnets 12 | private_subnets = var.vpc_private_subnets 13 | 14 | # Database Subnets 15 | database_subnets = var.vpc_database_subnets 16 | create_database_subnet_group = var.vpc_create_database_subnet_group 17 | create_database_subnet_route_table = var.vpc_create_database_subnet_route_table 18 | # create_database_internet_gateway_route = true 19 | # create_database_nat_gateway_route = true 20 | 21 | # NAT Gateways - Outbound Communication 22 | enable_nat_gateway = var.vpc_enable_nat_gateway 23 | single_nat_gateway = var.vpc_single_nat_gateway 24 | 25 | # VPC DNS Parameters 26 | enable_dns_hostnames = true 27 | enable_dns_support = true 28 | 29 | 30 | tags = local.common_tags 31 | vpc_tags = local.common_tags 32 | 33 | # Additional Tags to Subnets 34 | public_subnet_tags = { 35 | Type = "Public Subnets" 36 | } 37 | private_subnet_tags = { 38 | Type = "Private Subnets" 39 | } 40 | database_subnet_tags = { 41 | Type = "Private Database Subnets" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module-standardized/06-vpc-outputs.tf: -------------------------------------------------------------------------------- 1 | # VPC Output Values 2 | 3 | # VPC ID 4 | output "vpc_id" { 5 | description = "The ID of the VPC" 6 | value = module.vpc.vpc_id 7 | } 8 | 9 | # VPC CIDR blocks 10 | output "vpc_cidr_block" { 11 | description = "The CIDR block of the VPC" 12 | value = module.vpc.vpc_cidr_block 13 | } 14 | 15 | # VPC Private Subnets 16 | output "private_subnets" { 17 | description = "List of IDs of private subnets" 18 | value = module.vpc.private_subnets 19 | } 20 | 21 | # VPC Public Subnets 22 | output "public_subnets" { 23 | description = "List of IDs of public subnets" 24 | value = module.vpc.public_subnets 25 | } 26 | 27 | # VPC NAT gateway Public IP 28 | output "nat_public_ips" { 29 | description = "List of public Elastic IPs created for AWS NAT Gateway" 30 | value = module.vpc.nat_public_ips 31 | } 32 | 33 | # VPC AZs 34 | output "azs" { 35 | description = "A list of availability zones spefified as argument to this module" 36 | value = module.vpc.azs 37 | } -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module-standardized/terraform.tfvars: -------------------------------------------------------------------------------- 1 | # Generic Variables 2 | aws_region = "us-west-2" 3 | environment = "stag" 4 | business_division = "HR1" 5 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module-standardized/vpc.auto.tfvars: -------------------------------------------------------------------------------- 1 | # VPC Variables 2 | vpc_name = "myvpc" 3 | vpc_cidr_block = "10.0.0.0/16" 4 | vpc_availability_zones = ["us-west-1a", "us-west-1c"] 5 | vpc_public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] 6 | vpc_private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] 7 | vpc_database_subnets= ["10.0.151.0/24", "10.0.152.0/24"] 8 | vpc_create_database_subnet_group = true 9 | vpc_create_database_subnet_route_table = true 10 | vpc_enable_nat_gateway = true 11 | vpc_single_nat_gateway = true 12 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | 3 | # AWS Region 4 | variable "aws_region" { 5 | description = "Region in which AWS Resources to be created" 6 | type = string 7 | default = "us-west-1" 8 | } 9 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Block 2 | terraform { 3 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 3.0" 8 | } 9 | } 10 | } 11 | 12 | # Provider Block 13 | provider "aws" { 14 | region = var.aws_region 15 | profile = "default" 16 | } 17 | -------------------------------------------------------------------------------- /07 - Modules/example3-vpc/AWS-VPC-using-Terraform/terraform-manifests/vpc-module/vpc.tf: -------------------------------------------------------------------------------- 1 | # Create VPC Terraform Module 2 | module "vpc" { 3 | source = "terraform-aws-modules/vpc/aws" 4 | version = "3.11.5" 5 | 6 | name = "vpc-dev" 7 | cidr = "10.0.0.0/16" 8 | 9 | azs = ["us-west-1a", "us-west-1c"] 10 | private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] 11 | public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] 12 | 13 | enable_nat_gateway = true 14 | single_nat_gateway = true 15 | 16 | create_database_subnet_group = true 17 | create_database_subnet_route_table = true 18 | database_subnets = ["10.0.151.0/24", "10.0.152.0/24"] 19 | 20 | enable_dns_hostnames = true 21 | enable_dns_support = true 22 | 23 | public_subnet_tags = { 24 | Type = "public-subnets" 25 | } 26 | 27 | private_subnet_tags = { 28 | Type = "private-subnets" 29 | } 30 | 31 | database_subnet_tags = { 32 | Type = "database-subnets" 33 | } 34 | 35 | tags = { 36 | Owner = "Landmark" 37 | Environment = "dev" 38 | } 39 | vpc_tags = { 40 | Name = "vpc-dev" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /07 - Modules/terraform-eks/terraform-eks/README.md: -------------------------------------------------------------------------------- 1 | 2 | # **Landmark Technologies, Ontario, Canada.** 3 | ### **Contacts: +1437 215 2483
WebSite :
** 4 | ### **Email: mylandmarktech@gmail.com** 5 | 6 | 7 | 8 | ## Terraform Installation And Setup In AWS EC2 Redhat Instnace. 9 | ##### Prerequisite 10 | + AWS Acccount. 11 | + Create Redhat EC2 Instnace. 12 | + Create IAM Role With Required Policies. 13 | + VPCFullAccess 14 | + EC2FullAcces 15 | + S3FullAccess ..etc 16 | + Attach IAM Role to EC2 Instance. 17 | 18 | ### Install Terraform 19 | 20 | ``` sh 21 | $ sudo yum install wget unzip -y 22 | $ wget https://releases.hashicorp.com/terraform/0.12.26/terraform_0.12.26_linux_amd64.zip 23 | $ sudo unzip terraform_0.12.26_linux_amd64.zip -d /usr/local/bin/ 24 | # Export terraform binary path temporally 25 | $ export PATH=$PATH:/usr/local/bin 26 | # Add path permanently for current user.By Exporting path in .bashrc file at end of file. 27 | $ vi .bashrc 28 | export PATH="$PATH:/usr/local/bin" 29 | # Source .bashrc to reflect for current session 30 | $ source ~/.bashrc 31 | ``` 32 | #### Clone terraform scripts 33 | ``` sh 34 | $ git clone https://github.com/LandmakTechnology/terraform-eks 35 | $ cd Terraform_Scripts 36 | ``` 37 | #### Update Your Key Name in variables.tf file before executing terraform script. 38 | ## Infrastructure As A Code 39 | #### Create Infrastructure(VPC,Subnets,Route Tables,EC2 Instnaces ..etc) As A Code Using Terraform Scripts 40 | ``` sh 41 | # Initialise to install plugins 42 | $ terraform init VPC/ 43 | # Validate teffaform scripts 44 | $ terraform validate VPC/ 45 | # Plan terraform scripts which will list resources which is going be created. 46 | $ terraform plan VPC/ 47 | # Apply to create resources 48 | $ terraform apply --auto-approve VPC/ 49 | ``` 50 | 51 | ## Destroy Infrastructure 52 | ```sh 53 | $ terraform destroy --auto-approve VPC/ 54 | ``` 55 | -------------------------------------------------------------------------------- /08 - Terraform backend/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## **Sensitive values in state** 2 | 3 | - When you run Terraform commands with a local state file, Terraform stores the state as plain text, including variable values, even if you have flagged them as sensitive. Terraform needs to store these values in your state so that it can tell if you have changed them since the last time you applied your configuration. 4 | - Since Terraform state can contain sensitive values, you must keep your state file secure to avoid exposing this data. Refer to the Terraform documentation to learn more about securing your state file. 5 | 6 | ## **Backend** 7 | - Each Terraform configuration can specify a backend, which defines exactly where and how operations are performed, where state snapshots are stored, etc. 8 | 9 | - If a configuration includes no backend block, Terraform defaults to using the local backend, which performs operations on the local system and stores state as a plain file in the current working directory. 10 | 11 | - When changing backends, Terraform will give you the option to migrate your state to the new backend. This lets you adopt backends without losing any existing state. 12 | 13 | - You can change your backend configuration at any time. You can change both the configuration itself as well as the type of backend (for example from "consul" to "s3"). 14 | 15 | - Terraform will automatically detect any changes in your configuration and request a reinitialization. As part of the reinitialization process, Terraform will ask if you'd like to migrate your existing state to the new configuration. This allows you to easily switch from one backend to another. 16 | 17 | # **S3 Backend (with locking via DynamoDB)** 18 | - Stores the state as a given key in a given bucket on Amazon S3. This backend also supports state locking and consistency checking via Dynamo DB, which can be enabled by setting the dynamodb_table field to an existing DynamoDB table name. A single DynamoDB table can be used to lock multiple remote state files. Terraform generates key names that include the values of the bucket and key variables. 19 | 20 | - It is highly recommended that you enable Bucket Versioning on the S3 bucket to allow for state recovery in the case of accidental deletions and human error. 21 | 22 | ##**DynamoDB State Locking** 23 | The following configuration is optional: 24 | 25 | **dynamodb_table** 26 | - (Optional) Name of DynamoDB Table to use for state locking and consistency. The table must have a primary key named LockID with type of string. If not configured, state locking will be disabled. 27 | 28 | # **DynamoDB Table Permissions** 29 | If you are using state locking, Terraform will need the following AWS IAM permissions on the DynamoDB table (arn:aws:dynamodb:::table/mytable): 30 | 31 | dynamodb:GetItem 32 | dynamodb:PutItem 33 | dynamodb:DeleteItem 34 | 35 | 36 | ##**Data Source configurations** 37 | - To make use of the S3 remote state in another configuration, use the terraform_remote_state data source. 38 | 39 | data "terraform_remote_state" "network" { 40 | backend = "s3" 41 | config = { 42 | bucket = "terraform-state-prod" 43 | key = "network/terraform.tfstate" 44 | region = "us-east-1" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/remote-state-data-source/remote-backend/ami-datasource.tf: -------------------------------------------------------------------------------- 1 | # Get latest AMI ID for Amazon Linux2 OS 2 | data "aws_ami" "amzlinux2" { 3 | most_recent = true 4 | owners = ["amazon"] 5 | filter { 6 | name = "name" 7 | values = ["amzn2-ami-hvm-*-gp2"] 8 | } 9 | filter { 10 | name = "root-device-type" 11 | values = ["ebs"] 12 | } 13 | filter { 14 | name = "virtualization-type" 15 | values = ["hvm"] 16 | } 17 | filter { 18 | name = "architecture" 19 | values = ["x86_64"] 20 | } 21 | } -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/remote-state-data-source/remote-backend/backend.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "~> 3.0" 7 | } 8 | } 9 | 10 | 11 | backend "s3" { 12 | bucket = "my-terraformstate-landmark-buc" 13 | key = "terraform/terraform.tfstate" 14 | dynamodb_table = "terraform-lock" 15 | region = "us-west-1" 16 | 17 | } 18 | } 19 | /* 20 | resource "aws_s3_bucket" "my_bucket" { 21 | bucket = "my-terraformstate-landmark-buc" 22 | acl = "private" 23 | 24 | versioning { 25 | enabled = true 26 | } 27 | 28 | tags = { 29 | Name = "My terraform-bucket" 30 | Environment = "Dev" 31 | } 32 | } 33 | */ 34 | resource "aws_dynamodb_table" "tf_lock" { 35 | name = "terraform-lock" 36 | hash_key = "LockID" 37 | read_capacity = 3 38 | write_capacity = 3 39 | attribute { 40 | name = "LockID" 41 | type = "S" 42 | } 43 | tags = { 44 | Name = "Terraform Lock Table" 45 | } 46 | lifecycle { 47 | prevent_destroy = false 48 | } 49 | } 50 | 51 | 52 | 53 | # Provider Block 54 | provider "aws" { 55 | region = "us-west-1" 56 | profile = "landmark" 57 | } 58 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/remote-state-data-source/remote-backend/ec2.tf: -------------------------------------------------------------------------------- 1 | resource "aws_instance" "ec2" { 2 | ami = data.aws_ami.amzlinux2.id 3 | instance_type = var.my_instance_type 4 | 5 | tags = { 6 | "Name" = "Prod_ec2" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/remote-state-data-source/remote-backend/variables.tf: -------------------------------------------------------------------------------- 1 | variable "my_instance_type"{ 2 | type = string 3 | default = "t2.micro" 4 | } 5 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/vpc module/01-backend.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "~> 3.0" 7 | } 8 | } 9 | 10 | 11 | backend "s3" { 12 | bucket = "my-terraformstate-landmark-buc" 13 | key = "terraform/terraform.tfstate" 14 | dynamodb_table = "terraform-lock" 15 | 16 | region = "us-west-1" 17 | 18 | } 19 | } 20 | 21 | /*resource "aws_s3_bucket" "my_bucket" { 22 | bucket = "my-terraformstate-landmark-buc" 23 | acl = "private" 24 | 25 | versioning { 26 | enabled = true 27 | } 28 | 29 | tags = { 30 | Name = "My terraform-bucket" 31 | Environment = "Dev" 32 | } 33 | }*/ 34 | 35 | resource "aws_dynamodb_table" "tf_lock" { 36 | name = "terraform-lock" 37 | hash_key = "LockID" 38 | read_capacity = 3 39 | write_capacity = 3 40 | attribute { 41 | name = "LockID" 42 | type = "S" 43 | } 44 | tags = { 45 | Name = "Terraform Lock Table" 46 | } 47 | } 48 | 49 | # Provider Block 50 | provider "aws" { 51 | region = "us-west-1" 52 | profile = "Kenmak" 53 | } 54 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/vpc module/02-generic-variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | # AWS Region 3 | variable "aws_region" { 4 | description = "Region in which AWS Resources to be created" 5 | type = string 6 | default = "us-west-2" 7 | } 8 | # Environment Variable 9 | variable "environment" { 10 | description = "Environment Variable used as a prefix" 11 | type = string 12 | default = "dev" 13 | } 14 | # Business Division 15 | variable "business_division" { 16 | description = "Business Division in the large organization this Infrastructure belongs" 17 | type = string 18 | default = "FINANCE" 19 | } 20 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/vpc module/03-local-values.tf: -------------------------------------------------------------------------------- 1 | # Define Local Values in Terraform 2 | locals { 3 | owners = var.business_division 4 | environment = var.environment 5 | name = "${var.business_division}-${var.environment}" 6 | #name = "${local.owners}-${local.environment}" 7 | common_tags = { 8 | owners = local.owners 9 | environment = local.environment 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/vpc module/04-vpc-variables.tf: -------------------------------------------------------------------------------- 1 | # VPC Input Variables 2 | 3 | # VPC Name 4 | variable "vpc_name" { 5 | description = "VPC Name" 6 | type = string 7 | default = "myvpc" 8 | } 9 | 10 | # VPC CIDR Block 11 | variable "vpc_cidr_block" { 12 | description = "VPC CIDR Block" 13 | type = string 14 | default = "10.0.0.0/16" 15 | } 16 | 17 | # VPC Availability Zones 18 | variable "vpc_availability_zones" { 19 | description = "VPC Availability Zones" 20 | type = list(string) 21 | default = ["us-west-1a", "us-west-1c"] 22 | } 23 | 24 | # VPC Public Subnets 25 | variable "vpc_public_subnets" { 26 | description = "VPC Public Subnets" 27 | type = list(string) 28 | default = ["10.0.101.0/24", "10.0.102.0/24"] 29 | } 30 | 31 | # VPC Private Subnets 32 | variable "vpc_private_subnets" { 33 | description = "VPC Private Subnets" 34 | type = list(string) 35 | default = ["10.0.1.0/24", "10.0.2.0/24"] 36 | } 37 | 38 | # VPC Database Subnets 39 | variable "vpc_database_subnets" { 40 | description = "VPC Database Subnets" 41 | type = list(string) 42 | default = ["10.0.151.0/24", "10.0.152.0/24"] 43 | } 44 | 45 | # VPC Create Database Subnet Group (True / False) 46 | variable "vpc_create_database_subnet_group" { 47 | description = "VPC Create Database Subnet Group" 48 | type = bool 49 | default = true 50 | } 51 | 52 | # VPC Create Database Subnet Route Table (True or False) 53 | variable "vpc_create_database_subnet_route_table" { 54 | description = "VPC Create Database Subnet Route Table" 55 | type = bool 56 | default = true 57 | } 58 | 59 | 60 | # VPC Enable NAT Gateway (True or False) 61 | variable "vpc_enable_nat_gateway" { 62 | description = "Enable NAT Gateways for Private Subnets Outbound Communication" 63 | type = bool 64 | default = true 65 | } 66 | 67 | # VPC Single NAT Gateway (True or False) 68 | variable "vpc_single_nat_gateway" { 69 | description = "Enable only single NAT Gateway in one Availability Zone to save costs during our demos" 70 | type = bool 71 | default = true 72 | } 73 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/vpc module/05-vpc-module.tf: -------------------------------------------------------------------------------- 1 | # Create VPC Terraform Module 2 | module "vpc" { 3 | source = "terraform-aws-modules/vpc/aws" 4 | version = "3.11.0" 5 | #version = "~> 2.78" 6 | 7 | # VPC Basic Details 8 | name = "${local.name}-${var.vpc_name}" 9 | cidr = var.vpc_cidr_block 10 | azs = var.vpc_availability_zones 11 | public_subnets = var.vpc_public_subnets 12 | private_subnets = var.vpc_private_subnets 13 | instance_tenancy = "default" 14 | 15 | # Database Subnets 16 | database_subnets = var.vpc_database_subnets 17 | create_database_subnet_group = var.vpc_create_database_subnet_group 18 | create_database_subnet_route_table = var.vpc_create_database_subnet_route_table 19 | # create_database_internet_gateway_route = true 20 | # create_database_nat_gateway_route = true 21 | 22 | # NAT Gateways - Outbound Communication 23 | enable_nat_gateway = var.vpc_enable_nat_gateway 24 | single_nat_gateway = var.vpc_single_nat_gateway 25 | 26 | # VPC DNS Parameters 27 | enable_dns_hostnames = true 28 | enable_dns_support = true 29 | 30 | 31 | tags = local.common_tags 32 | vpc_tags = local.common_tags 33 | 34 | # Additional Tags to Subnets 35 | public_subnet_tags = { 36 | Type = "Public Subnets" 37 | } 38 | private_subnet_tags = { 39 | Type = "Private Subnets" 40 | } 41 | database_subnet_tags = { 42 | Type = "Private Database Subnets" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/vpc module/06-vpc-outputs.tf: -------------------------------------------------------------------------------- 1 | # VPC Output Values 2 | 3 | # VPC ID 4 | output "vpc_id" { 5 | description = "The ID of the VPC" 6 | value = module.vpc.vpc_id 7 | } 8 | 9 | # VPC CIDR blocks 10 | output "vpc_cidr_block" { 11 | description = "The CIDR block of the VPC" 12 | value = module.vpc.vpc_cidr_block 13 | } 14 | 15 | # VPC Private Subnets 16 | output "private_subnets" { 17 | description = "List of IDs of private subnets" 18 | value = module.vpc.private_subnets 19 | } 20 | 21 | # VPC Public Subnets 22 | output "public_subnets" { 23 | description = "List of IDs of public subnets" 24 | value = module.vpc.public_subnets 25 | } 26 | 27 | # VPC NAT gateway Public IP 28 | output "nat_public_ips" { 29 | description = "List of public Elastic IPs created for AWS NAT Gateway" 30 | value = module.vpc.nat_public_ips 31 | } 32 | 33 | # VPC AZs 34 | output "azs" { 35 | description = "A list of availability zones spefified as argument to this module" 36 | value = module.vpc.azs 37 | } -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/vpc module/terraform.tfvars: -------------------------------------------------------------------------------- 1 | # Generic Variables 2 | aws_region = "us-west-1" 3 | environment = "stag" 4 | business_division = "HR" 5 | -------------------------------------------------------------------------------- /08 - Terraform backend/Remote state/vpc module/vpc.auto.tfvars: -------------------------------------------------------------------------------- 1 | # VPC Variables 2 | vpc_name = "myvpc" 3 | vpc_cidr_block = "10.0.0.0/16" 4 | vpc_availability_zones = ["us-west-1a", "us-west-1c"] 5 | vpc_public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] 6 | vpc_private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] 7 | vpc_database_subnets= ["10.0.151.0/24", "10.0.152.0/24"] 8 | vpc_create_database_subnet_group = true 9 | vpc_create_database_subnet_route_table = true 10 | vpc_enable_nat_gateway = true 11 | vpc_single_nat_gateway = true 12 | -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/01-backend.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "~> 3.0" 7 | } 8 | } 9 | 10 | 11 | backend "s3" { 12 | bucket = "my-terraformstate-landmark-buc" 13 | key = "terraform/terraform.tfstate" 14 | dynamodb_table = "terraform-lock" 15 | 16 | region = "us-west-1" 17 | 18 | } 19 | } 20 | 21 | /*resource "aws_s3_bucket" "my_bucket" { 22 | bucket = "my-terraformstate-landmark-buc" 23 | acl = "private" 24 | 25 | versioning { 26 | enabled = true 27 | } 28 | 29 | tags = { 30 | Name = "My terraform-bucket" 31 | Environment = "Dev" 32 | } 33 | }*/ 34 | 35 | resource "aws_dynamodb_table" "tf_lock" { 36 | name = "terraform-lock" 37 | hash_key = "LockID" 38 | read_capacity = 3 39 | write_capacity = 3 40 | attribute { 41 | name = "LockID" 42 | type = "S" 43 | } 44 | tags = { 45 | Name = "Terraform Lock Table" 46 | } 47 | } 48 | 49 | # Provider Block 50 | provider "aws" { 51 | region = "us-west-1" 52 | profile = "Kenmak" 53 | } 54 | -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/02-generic-variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | # AWS Region 3 | variable "aws_region" { 4 | description = "Region in which AWS Resources to be created" 5 | type = string 6 | default = "us-west-2" 7 | } 8 | # Environment Variable 9 | variable "environment" { 10 | description = "Environment Variable used as a prefix" 11 | type = string 12 | default = "dev" 13 | } 14 | # Business Division 15 | variable "business_division" { 16 | description = "Business Division in the large organization this Infrastructure belongs" 17 | type = string 18 | default = "FINANCE" 19 | } 20 | -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/03-local-values.tf: -------------------------------------------------------------------------------- 1 | # Define Local Values in Terraform 2 | locals { 3 | owners = var.business_division 4 | environment = var.environment 5 | name = "${var.business_division}-${var.environment}" 6 | #name = "${local.owners}-${local.environment}" 7 | common_tags = { 8 | owners = local.owners 9 | environment = local.environment 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/04-vpc-variables.tf: -------------------------------------------------------------------------------- 1 | # VPC Input Variables 2 | 3 | # VPC Name 4 | variable "vpc_name" { 5 | description = "VPC Name" 6 | type = string 7 | default = "myvpc" 8 | } 9 | 10 | # VPC CIDR Block 11 | variable "vpc_cidr_block" { 12 | description = "VPC CIDR Block" 13 | type = string 14 | default = "10.0.0.0/16" 15 | } 16 | 17 | # VPC Availability Zones 18 | variable "vpc_availability_zones" { 19 | description = "VPC Availability Zones" 20 | type = list(string) 21 | default = ["us-west-1a", "us-west-1c"] 22 | } 23 | 24 | # VPC Public Subnets 25 | variable "vpc_public_subnets" { 26 | description = "VPC Public Subnets" 27 | type = list(string) 28 | default = ["10.0.101.0/24", "10.0.102.0/24"] 29 | } 30 | 31 | # VPC Private Subnets 32 | variable "vpc_private_subnets" { 33 | description = "VPC Private Subnets" 34 | type = list(string) 35 | default = ["10.0.1.0/24", "10.0.2.0/24"] 36 | } 37 | 38 | # VPC Database Subnets 39 | variable "vpc_database_subnets" { 40 | description = "VPC Database Subnets" 41 | type = list(string) 42 | default = ["10.0.151.0/24", "10.0.152.0/24"] 43 | } 44 | 45 | # VPC Create Database Subnet Group (True / False) 46 | variable "vpc_create_database_subnet_group" { 47 | description = "VPC Create Database Subnet Group" 48 | type = bool 49 | default = true 50 | } 51 | 52 | # VPC Create Database Subnet Route Table (True or False) 53 | variable "vpc_create_database_subnet_route_table" { 54 | description = "VPC Create Database Subnet Route Table" 55 | type = bool 56 | default = true 57 | } 58 | 59 | 60 | # VPC Enable NAT Gateway (True or False) 61 | variable "vpc_enable_nat_gateway" { 62 | description = "Enable NAT Gateways for Private Subnets Outbound Communication" 63 | type = bool 64 | default = true 65 | } 66 | 67 | # VPC Single NAT Gateway (True or False) 68 | variable "vpc_single_nat_gateway" { 69 | description = "Enable only single NAT Gateway in one Availability Zone to save costs during our demos" 70 | type = bool 71 | default = true 72 | } 73 | -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/05-vpc-module.tf: -------------------------------------------------------------------------------- 1 | # Create VPC Terraform Module 2 | module "vpc" { 3 | source = "terraform-aws-modules/vpc/aws" 4 | version = "2.78.0" 5 | #version = "~> 2.78" 6 | 7 | # VPC Basic Details 8 | name = "${local.name}-${var.vpc_name}" 9 | cidr = var.vpc_cidr_block 10 | azs = var.vpc_availability_zones 11 | public_subnets = var.vpc_public_subnets 12 | private_subnets = var.vpc_private_subnets 13 | 14 | # Database Subnets 15 | database_subnets = var.vpc_database_subnets 16 | create_database_subnet_group = var.vpc_create_database_subnet_group 17 | create_database_subnet_route_table = var.vpc_create_database_subnet_route_table 18 | # create_database_internet_gateway_route = true 19 | # create_database_nat_gateway_route = true 20 | 21 | # NAT Gateways - Outbound Communication 22 | enable_nat_gateway = var.vpc_enable_nat_gateway 23 | single_nat_gateway = var.vpc_single_nat_gateway 24 | 25 | # VPC DNS Parameters 26 | enable_dns_hostnames = true 27 | enable_dns_support = true 28 | 29 | 30 | tags = local.common_tags 31 | vpc_tags = local.common_tags 32 | 33 | # Additional Tags to Subnets 34 | public_subnet_tags = { 35 | Type = "Public Subnets" 36 | } 37 | private_subnet_tags = { 38 | Type = "Private Subnets" 39 | } 40 | database_subnet_tags = { 41 | Type = "Private Database Subnets" 42 | } 43 | } -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/06-vpc-outputs.tf: -------------------------------------------------------------------------------- 1 | # VPC Output Values 2 | 3 | # VPC ID 4 | output "vpc_id" { 5 | description = "The ID of the VPC" 6 | value = module.vpc.vpc_id 7 | } 8 | 9 | # VPC CIDR blocks 10 | output "vpc_cidr_block" { 11 | description = "The CIDR block of the VPC" 12 | value = module.vpc.vpc_cidr_block 13 | } 14 | 15 | # VPC Private Subnets 16 | output "private_subnets" { 17 | description = "List of IDs of private subnets" 18 | value = module.vpc.private_subnets 19 | } 20 | 21 | # VPC Public Subnets 22 | output "public_subnets" { 23 | description = "List of IDs of public subnets" 24 | value = module.vpc.public_subnets 25 | } 26 | 27 | # VPC NAT gateway Public IP 28 | output "nat_public_ips" { 29 | description = "List of public Elastic IPs created for AWS NAT Gateway" 30 | value = module.vpc.nat_public_ips 31 | } 32 | 33 | # VPC AZs 34 | output "azs" { 35 | description = "A list of availability zones spefified as argument to this module" 36 | value = module.vpc.azs 37 | } -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/remote-data-source/ami-datasource.tf: -------------------------------------------------------------------------------- 1 | # Get latest AMI ID for Amazon Linux2 OS 2 | data "aws_ami" "amzlinux2" { 3 | most_recent = true 4 | owners = ["amazon"] 5 | filter { 6 | name = "name" 7 | values = ["amzn2-ami-hvm-*-gp2"] 8 | } 9 | filter { 10 | name = "root-device-type" 11 | values = ["ebs"] 12 | } 13 | filter { 14 | name = "virtualization-type" 15 | values = ["hvm"] 16 | } 17 | filter { 18 | name = "architecture" 19 | values = ["x86_64"] 20 | } 21 | } -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/remote-data-source/remote-ec2.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.0" # which means any version equal & above 0.14 like 0.15, 0.16 etc and < 1.xx 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "~> 3.0" 7 | } 8 | } 9 | } 10 | # Provider Block 11 | provider "aws" { 12 | region = "us-west-1" 13 | profile = "Kenmak" 14 | } 15 | 16 | data "terraform_remote_state" "network" { 17 | backend = "s3" 18 | config = { 19 | bucket = "my-terraformstate-landmark-buc" 20 | key = "terraform/terraform.tfstate" 21 | region = "us-west-1" 22 | } 23 | } 24 | 25 | /*data "terraform_remote_state" "network" { 26 | backend = "local" 27 | config = { 28 | path = "../remote-data-source/terraform.tfstate" 29 | } 30 | }*/ 31 | 32 | resource "aws_instance" "my-ec2"{ 33 | ami = data.aws_ami.amzlinux2.id 34 | instance_type = "t2.micro" 35 | subnet_id = data.terraform_remote_state.network.outputs.public_subnets[1] 36 | 37 | tags = { 38 | "Name" = "My_ec2" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/terraform.tfvars: -------------------------------------------------------------------------------- 1 | # Generic Variables 2 | aws_region = "us-west-1" 3 | environment = "stag" 4 | business_division = "HR" 5 | -------------------------------------------------------------------------------- /09 - Remote state data source/remote-state-data-source/vpc.auto.tfvars: -------------------------------------------------------------------------------- 1 | # VPC Variables 2 | vpc_name = "myvpc" 3 | vpc_cidr_block = "10.0.0.0/16" 4 | vpc_availability_zones = ["us-west-1a", "us-west-1c"] 5 | vpc_public_subnets = ["10.0.101.0/24", "10.0.102.0/24"] 6 | vpc_private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] 7 | vpc_database_subnets= ["10.0.151.0/24", "10.0.152.0/24"] 8 | vpc_create_database_subnet_group = true 9 | vpc_create_database_subnet_route_table = true 10 | vpc_enable_nat_gateway = true 11 | vpc_single_nat_gateway = true 12 | --------------------------------------------------------------------------------