├── .github └── workflows │ └── jekyll.yml ├── .gitignore ├── Gemfile ├── README.md ├── Terraform_Resource_Identifier.png ├── _config.yml ├── _layouts ├── collabnix-logo.png └── default.html ├── assets └── css │ └── style.scss ├── beginners ├── README.md ├── aws │ ├── README.md │ ├── backend.tf │ ├── eks │ │ ├── README.md │ │ ├── eks-cluster.tf │ │ ├── kubernetes-dashboard-admin.rbac.yaml │ │ ├── outputs.tf │ │ ├── provider.tf │ │ ├── results.txt │ │ ├── security-groups.tf │ │ ├── versions.tf │ │ └── vpc.tf │ ├── main.tf │ ├── modules │ │ ├── API_Gateway & CloudWatch │ │ │ ├── CloudWatch_dashboard.tf │ │ │ ├── README.md │ │ │ ├── api_gateway.tf │ │ │ ├── provider.tf │ │ │ ├── route53_health_check.tf │ │ │ └── var.json.tf │ │ ├── application_load_balancer │ │ │ ├── README.md │ │ │ ├── instances.tf │ │ │ ├── loadbalancer.tf │ │ │ ├── provider.tf │ │ │ ├── security_group.tf │ │ │ └── target_group_attach.tf │ │ ├── ec2 │ │ │ ├── ec2.tf │ │ │ ├── key.pem │ │ │ ├── keypair.tf │ │ │ ├── networkinterface.tf │ │ │ ├── outputs.tf │ │ │ ├── public.pem │ │ │ └── variables.tf │ │ ├── ec2_apache_webserver │ │ │ ├── bootscript.sh │ │ │ ├── ec2.tf │ │ │ ├── key.pem │ │ │ ├── keypair.tf │ │ │ ├── networkinterface.tf │ │ │ ├── outputs.tf │ │ │ ├── public.pem │ │ │ └── variables.tf │ │ ├── s3 │ │ │ ├── README.md │ │ │ ├── error.html │ │ │ ├── index.html │ │ │ ├── outputs.tf │ │ │ ├── s3.tf │ │ │ └── variables.tf │ │ └── vpc │ │ │ ├── eip.tf │ │ │ ├── internetgateway.tf │ │ │ ├── main.tf │ │ │ ├── natgateway.tf │ │ │ ├── outputs.tf │ │ │ ├── routetable.tf │ │ │ ├── subnet.tf │ │ │ └── variables.tf │ └── provider.tf ├── azure │ ├── README.md │ ├── aks_cluster │ │ ├── README.md │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf │ ├── linuxVM │ │ ├── README.md │ │ ├── linuxvm.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── module_example │ │ ├── README.md │ │ ├── child_module │ │ │ ├── README.md │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── multiple_resources │ │ ├── README.md │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── storageAccount │ │ ├── 404.html │ │ ├── README.md │ │ ├── index.html │ │ ├── outputs.tf │ │ ├── storageaccount.tf │ │ └── variables.tf │ ├── virtualnetwork │ │ ├── README.md │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ └── windowsVM │ │ ├── README.md │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── windowsvm.tf ├── gcp │ ├── README.md │ ├── TerraformVsGoogleDeploymentManager │ │ └── README.md │ ├── virtual-machine │ │ ├── README.md │ │ ├── compute-address.tf │ │ ├── compute-disk.tf │ │ ├── compute-instance.tf │ │ ├── outputs.tf │ │ ├── providers.tf │ │ └── variables.tf │ └── vpc │ │ ├── README.md │ │ ├── firewall.tf │ │ ├── outputs.tf │ │ ├── providers.tf │ │ ├── variables.tf │ │ └── vpc.tf ├── init-plan-apply │ └── README.md ├── os │ ├── linux │ │ └── README.md │ ├── mac │ │ └── README.md │ └── windows │ │ └── README.md ├── providers │ └── Terraform_Providers.md ├── rds-restore │ ├── README.md │ ├── main.tf │ └── restore.tf └── resources │ ├── Terraform_Resources.md │ └── variables │ └── README.md ├── certification ├── 1.Understand infrastructure as code (IaC) concepts │ └── Questions.md ├── 2.Understand Terraform's purpose (vs other IaC) │ └── Questions.md ├── 3.Understand Terraform basics │ └── Questions.md ├── 4.Use the Terraform CLI (outside of core workflow) │ └── Questions.md ├── 5.Interact with Terraform modules │ └── Questions.md ├── 6.Navigate Terraform workflow │ └── Questions.md ├── 7.Implement and maintain state │ └── Questions.md ├── 8.Read, generate, and modify configuration │ └── Questions.md ├── 9.Understand Terraform Cloud and Enterprise capabilities │ └── Questions.md └── README.md ├── experts └── README.md ├── getting-started ├── README.md ├── iac.md ├── terraform.md ├── the-problem.md └── use-cases.md ├── images ├── Azure_staticwebsite_Error.png ├── Azure_staticwebsite_Success.png ├── README.md ├── Terraform-Provisioners.png ├── TerraformVsDeployMgr.jpg ├── Terraform_Resource_Identifier.png ├── Terraform_Resource_definition.png ├── aws_website_error.png ├── aws_website_success.png ├── terraformenv.JPG └── wordle.png ├── intermediate ├── README.md ├── Terraform-Functions │ ├── All_Outputs.txt │ ├── FileSystem_Functions.tf │ ├── IP_Network_Functions.tf │ ├── Numeric_Functions.tf │ ├── String_Collection_Functions.tf │ ├── file1.txt │ └── output.tmpl └── azure │ └── Terraform-Provisioners │ ├── README.md │ ├── linuxvm.tf │ └── variables.tf └── jekyll-theme-hacker.gemspec /.github/workflows/jekyll.yml: -------------------------------------------------------------------------------- 1 | name: Jekyll site CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Build the site in the jekyll/builder container 17 | run: | 18 | docker run \ 19 | -v ${{ github.workspace }}:/srv/jekyll -v ${{ github.workspace }}/_site:/srv/jekyll/_site \ 20 | jekyll/builder:latest /bin/bash -c "chmod -R 777 /srv/jekyll && jekyll build --future" 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## 2 | # Terraform repo .gitignore 3 | # Source: https://github.com/github/gitignore/blob/master/Terraform.gitignore 4 | ## 5 | 6 | # Local .terraform directories 7 | **/.terraform/* 8 | 9 | # .tfstate files 10 | *.tfstate 11 | *.tfstate.* 12 | 13 | # Crash log files 14 | crash.log 15 | 16 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 17 | # .tfvars files are managed as part of configuration and so should be included in 18 | # version control. 19 | 20 | *.tfvars 21 | *.auto.tfvars 22 | 23 | # Ignore override files as they are usually used to override resources locally and so 24 | # are not checked in 25 | override.tf 26 | override.tf.json 27 | *_override.tf 28 | *_override.tf.json 29 | 30 | # Include override files you do wish to add to version control using negated pattern 31 | # 32 | # !example_override.tf 33 | 34 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 35 | # example: *tfplan* 36 | 37 | *.tfplan* 38 | 39 | .DS_Store -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in jekyll-admin.gemspec 4 | gemspec 5 | 6 | # Site dependencies 7 | gem 'jekyll-seo-tag' 8 | gem 'jekyll-sitemap' 9 | gem 'jekyll-admin', group: :jekyll_plugins 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # An Ultimate Terraform Hands-on Labs 3 | 4 | 5 | 6 | ![My image](https://raw.githubusercontent.com/collabnix/terraform/master/images/wordle.png) 7 | 8 | Terraform Labs brings you tutorials that help you get hands-on experience using Terraform, Kubernetes & Cloud. Here you will find complete documentation of labs and tutorials around Terraform CLI, Configuration Language, sub-commands, providers, Registry and much more.. 9 | 10 | # Getting Started in 3 Simple Steps 11 | 12 | - Join 5000+ Collabnix Labs Contributors in 2 mins via [Slack](https://launchpass.com/collabnix) 13 | 14 | - Fork, Contribute & Share via [Terraform GITHUB Repository](https://github.com/collabnix/terraform) 15 | 16 | - [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/fold_left.svg?style=social&label=Follow%20%40collabnix)](https://twitter.com/collabnix) 17 | 18 | # Terraform Workshop/Labs 19 | 20 | - [Getting Started: Why, What & How about Terraform?](getting-started/README.md) 21 | 22 | - [The problem of provisioning everything manually](getting-started/the-problem.md) 23 | - [The concept of Infrastructure as a Code (IaC)](getting-started/iac.md) 24 | - [Where terraform comes in?](getting-started/terraform.md) 25 | - [Use cases of Terraform](getting-started/use-cases.md) 26 | - [Terraform Vs Ansible]() 27 | - [Terraform Vs Chef]() 28 | - [Terraform Vs Puppet]() 29 | 30 | 31 | # Terraform Beginners Track 32 | 33 | ## Installing Terraform 34 | 35 | - [MacOS](https://github.com/collabnix/terraform/blob/master/beginners/os/mac/README.md) 36 | - [Linux](https://github.com/collabnix/terraform/tree/master/beginners/os/linux) 37 | - [Windows](https://github.com/collabnix/terraform/tree/master/beginners/os/windows) 38 | 39 | 40 | ## From Terraform INIT To APPLY 41 | 42 | - [Terraform providers](https://github.com/collabnix/terraform/blob/master/beginners/providers/Terraform_Providers.md) 43 | - [Terraform resources](https://github.com/collabnix/terraform/blob/master/beginners/resources/Terraform_Resources.md) 44 | - [Variable Resources](https://github.com/collabnix/terraform/blob/master/beginners/resources/variables/README.md) 45 | - [Output Resources](https://github.com/collabnix/terraform/blob/master/beginners/resources/output/README.md) 46 | - [Terraform CLI](https://github.com/collabnix/terraform/blob/master/beginners/CLI/README.md) 47 | - [Init-plan-apply !](https://github.com/collabnix/terraform/blob/master/beginners/init-plan-apply/README.md) 48 | 49 | ## Setting up Cloud Account 50 | 51 | #### AWS 52 | 53 | - [Deploy your AWS EKS cluster with Terraform](https://github.com/collabnix/terraform/tree/master/beginners/aws/eks) 54 | - Setting up AWS account credentials 55 | - Launch an EC2 instance 56 | - Create a S3 bucket for storage 57 | - Launch an RDS with mysql engine 58 | - Deploy a Single Web Server 59 | - Deploy a Configurable Web Server 60 | - Deploy Cluster of Web Servers 61 | - Deploy a Load Balancer 62 | - Create a VPC 63 | - Deploy a subnet in VPC with security groups/firewall rules 64 | - Cleaning Up 65 | 66 | #### Azure 67 | 68 | - [Getting started with Terraform in Azure](https://github.com/collabnix/terraform/blob/master/beginners/azure/README.md) 69 | - [Create a Virtual Network in Azure](https://github.com/collabnix/terraform/blob/master/beginners/azure/virtualnetwork) 70 | - [Create a Linux Virtual Machine in Azure](https://github.com/collabnix/terraform/tree/master/beginners/azure/linuxVM) 71 | - [Create a Windows-10 Virtual Machine in Azure](https://github.com/collabnix/terraform/tree/master/beginners/azure/windowsVM) 72 | - [Create a Storage account and Host a static website in Azure](https://github.com/collabnix/terraform/tree/master/beginners/azure/storageAccount) 73 | - [Create Multiple Resources in Azure using for_each](https://github.com/collabnix/terraform/tree/master/beginners/azure/multiple_resources) 74 | - [Create AKS Cluster with Container Monitoring](https://github.com/collabnix/terraform/tree/master/beginners/azure/aks_cluster) 75 | - [How to use Modules](https://github.com/collabnix/terraform/tree/master/beginners/azure/module_example) 76 | 77 | #### GCP 78 | 79 | - [Setting up Terraform for Google Cloud Platform](https://github.com/collabnix/terraform/blob/master/beginners/gcp/README.md) 80 | - Terraform vs Google Deployment Manager 81 | - Launch a Compute Engine Instance 82 | - Create a New VPC and Public Subnet 83 | - Auto Scale and Load Balance the Managed Instance Groups 84 | - Deploy a web server 85 | - Cleaning Up 86 | 87 | ## Managing Terraform State 88 | 89 | - What is Terraform State 90 | - Shared Storage for State Files 91 | - Locking State Files 92 | - Isolating State Files 93 | - File Layouts 94 | - Read-only States 95 | - Import Terraform state 96 | 97 | ## Terraform Backends 98 | 99 | - What are terraform backends ? 100 | - List of supported Remote backends 101 | - Using remote backends in a collaborative environments 102 | 103 | ## Terraform Modules 104 | 105 | - Why Terraform Modules 106 | - When to write Terraform Modules 107 | 108 | 109 | ## Terraform Enterprise (TFE) 110 | - Additional features of TFE 111 | - Integration of TFE with Github 112 | - Creating organisation 113 | - Configuring backends 114 | 115 | 116 | 117 | - [Intermediate Track](./intermediate/README.md) - In-Progress 118 | 119 | - [Experts Track](./experts/README.md) - Not Started 120 | 121 | 122 | # Terraform Associate Certification 123 | 124 | - [Study Guide](https://learn.hashicorp.com/terraform/certification/terraform-associate-study-guide)
125 | - [HashiCorp Infrastructure Automation Certification](https://www.hashicorp.com/certification/terraform-associate/)
126 | - [Sample Questions](https://learn.hashicorp.com/terraform/certification/terraform-associate-sample-questions)
127 | 128 | # Core Contributors 129 | 130 | 131 | -------------------------------------------------------------------------------- /Terraform_Resource_Identifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/Terraform_Resource_Identifier.png -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | show_downloads: true 2 | google_analytics: 3 | theme: jekyll-theme-cayman 4 | jekyll_admin: 5 | hidden_links: 6 | - posts 7 | - pages 8 | - staticfiles 9 | - datafiles 10 | - configuration 11 | -------------------------------------------------------------------------------- /_layouts/collabnix-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/_layouts/collabnix-logo.png -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% if site.google_analytics %} 6 | 7 | 13 | {% endif %} 14 | 15 | 16 | {% seo %} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 46 | 47 |
48 | 49 | {{ content }} 50 | 51 | 52 | 69 |
70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import 'jekyll-theme-cayman'; 5 | -------------------------------------------------------------------------------- /beginners/README.md: -------------------------------------------------------------------------------- 1 | # Terraform Beginners Track 2 | 3 | ## Installing Terraform 4 | 5 | - [MacOS](https://github.com/collabnix/terraform/blob/master/beginners/os/mac/README.md) 6 | - [Linux](https://github.com/collabnix/terraform/tree/master/beginners/os/linux) 7 | - [Windows](https://github.com/collabnix/terraform/tree/master/beginners/os/windows) 8 | - [Raspberry Pi]() 9 | 10 | ## From Terraform INIT To APPLY 11 | 12 | - [Terraform providers](https://github.com/collabnix/terraform/blob/master/beginners/providers/README.md) 13 | - [Terraform resources](https://github.com/collabnix/terraform/blob/master/beginners/resources/README.md) 14 | - [Variable Resources](https://github.com/collabnix/terraform/blob/master/beginners/resources/variables/README.md) 15 | - [Output Resources](https://github.com/collabnix/terraform/blob/master/beginners/resources/output/README.md) 16 | - [Terraform CLI](https://github.com/collabnix/terraform/blob/master/beginners/CLI/README.md) 17 | - [Init-plan-apply !](https://github.com/collabnix/terraform/blob/master/beginners/init-plan-apply/README.md) 18 | 19 | ## Setting up Cloud Account 20 | 21 | #### AWS 22 | 23 | - Setting up AWS account credentials 24 | - Launch an EC2 instance 25 | - Create a S3 bucket for storage 26 | - Launch an RDS with mysql engine 27 | - Deploy a Single Web Server 28 | - Deploy a Configurable Web Server 29 | - Deploy Cluster of Web Servers 30 | - Deploy a Load Balancer 31 | - Create a VPC 32 | - Deploy a subnet in VPC with security groups/firewall rules 33 | - Cleaning Up 34 | 35 | #### Azure 36 | 37 | - [Getting started with Terraform in Azure](https://github.com/collabnix/terraform/blob/master/beginners/azure/README.md) 38 | - [Create a Virtual Network in Azure](https://github.com/collabnix/terraform/blob/master/beginners/azure/virtualnetwork) 39 | - [Create a Linux Virtual Machine in Azure](https://github.com/collabnix/terraform/tree/master/beginners/azure/linuxVM) 40 | - [Create a Windows-10 Virtual Machine in Azure](https://github.com/collabnix/terraform/tree/master/beginners/azure/windowsVM) 41 | - [Create a Storage account and Host a static website in Azure](https://github.com/collabnix/terraform/tree/master/beginners/azure/storageAccount) 42 | - [Create Multiple Resources in Azure using for_each](https://github.com/collabnix/terraform/tree/master/beginners/azure/multiple_resources) 43 | - [Create AKS Cluster with Container Monitoring](https://github.com/collabnix/terraform/tree/master/beginners/azure/aks_cluster) 44 | 45 | - [How to use Modules](https://github.com/collabnix/terraform/tree/master/beginners/azure/module_example) 46 | 47 | ### GCP 48 | 49 | - [Setting up Terraform for Google Cloud Platform](https://github.com/collabnix/terraform/blob/master/beginners/gcp/README.md) 50 | - Terraform vs Google Deployment Manager 51 | - Launch a Compute Engine Instance 52 | - Create a New VPC and Public Subnet 53 | - Auto Scale and Load Balance the Managed Instance Groups 54 | - Deploy a web server 55 | - Cleaning Up 56 | 57 | ## Managing Terraform State 58 | 59 | - What is Terraform State 60 | - Shared Storage for State Files 61 | - Locking State Files 62 | - Isolating State Files 63 | - File Layouts 64 | - Read-only States 65 | - Import Terraform state 66 | 67 | ## Terraform Backends 68 | 69 | - What are terraform backends ? 70 | - List of supported Remote backends 71 | - Using remote backends in a collaborative environments 72 | 73 | ## Terraform Modules 74 | 75 | - Why Terraform Modules 76 | - When to write Terraform Modules 77 | 78 | 79 | ## Terrafrom Enterprise (TFE) 80 | - Additional features of TFE 81 | - Integration of TFE with Github 82 | - Creating organisation 83 | - Configuring backends 84 | -------------------------------------------------------------------------------- /beginners/aws/README.md: -------------------------------------------------------------------------------- 1 | # Terraform Beginners Track - Amazon Web Services 2 | 3 | ## Prerequisites 4 | 5 | - Any Code Editor (Visual Studio Code or Atom etc) 6 | - AWS Subscription. 7 | 8 | - Hashicorp Terraform installed and added to the PATH 9 | - A local AWS Secret profile or If you are running this on EC2 instance then Instance Role must have necessary access to create Network resources 10 | - Select the module and its corresponding dependent module which you want to build in main.tf file -------------------------------------------------------------------------------- /beginners/aws/backend.tf: -------------------------------------------------------------------------------- 1 | terraform{ 2 | backend "s3" { 3 | bucket = "s3bucketName" // s3 bucket name created from AWS console 4 | key = "terraform.tfstate" // terraform state file 5 | region = "" // provide s3 bucket region 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /beginners/aws/eks/README.md: -------------------------------------------------------------------------------- 1 | # Deploy your AWS EKS cluster with Terraform 2 | 3 | The purpose of this tutorial is to create an EKS cluster with Terraform. Amazon Elastic Kubernetes Service (Amazon EKS) is a fully managed Kubernetes service by AWS. To go deeper you can read this article which explains another way to deploy an EKS cluster with eksctl. 4 | 5 | 6 | ## Pre-requisite: 7 | 8 | - MacOS 9 | - Get an AWS free trial account 10 | - Install Terraform v0.12.26 11 | 12 | ``` 13 | brew install terraform 14 | ``` 15 | 16 | If you're running Terraform 0.11, I would suggest to upgrade it to 0.12 ASAP. 17 | 18 | 19 | - Install AWSCLI 2.0.17 20 | 21 | ``` 22 | brew install awscli 23 | ``` 24 | 25 | - Install AWS IAM Authenticator 26 | 27 | ``` 28 | brew install aws-iam-authenticator 29 | ``` 30 | 31 | - Install WGET 32 | 33 | ``` 34 | brew install wget 35 | ``` 36 | 37 | - Install Kubectl 38 | 39 | ``` 40 | brew install kubernetes-cli 41 | ``` 42 | 43 | 44 | ## Setting up AWS IAM users for Terraform 45 | 46 | The first thing to set up is your Terraform. We will create an AWS IAM users for Terraform. 47 | 48 | In your AWS console, go to the IAM section and create a user named “SudoAccess”. Then add your user to a group named “SudoAccessGroup”. 49 | Attaches to this group the following rights: 50 | 51 | - AdministratorAccess 52 | - AmazonEKSClusterPolicy 53 | 54 | After these steps, AWS will provide you a Secret Access Key and Access Key ID. 55 | Save them preciously because this will be the only time AWS gives it to you. 56 | 57 | In your own console, create a ~/.aws/credentials file and put your credentials in it: 58 | 59 | 60 | ``` 61 | [default] 62 | aws_access_key_id=*********** 63 | aws_secret_access_key=**************************** 64 | ``` 65 | 66 | ## Creating Config file 67 | 68 | ``` 69 | cat config 70 | [default] 71 | region=us-east-2 72 | ``` 73 | 74 | ## Cloning the Repository 75 | 76 | ``` 77 | git clone https://github.com/hashicorp/learn-terraform-provision-eks-cluster 78 | ``` 79 | 80 | You can explore this repository by changing directories or navigating in your UI. 81 | 82 | ``` 83 | $ cd learn-terraform-provision-eks-cluster 84 | ``` 85 | 86 | In here, you will find six files used to provision a VPC, security groups and an EKS cluster. The final product should be similar to this: 87 | 88 | 89 | - vpc.tf provisions a VPC, subnets and availability zones using the AWS VPC Module. A new VPC is created for this guide so it doesn't impact your existing cloud environment and resources. 90 | 91 | - security-groups.tf provisions the security groups used by the EKS cluster. 92 | 93 | - eks-cluster.tf provisions all the resources (AutoScaling Groups, etc...) required to set up an EKS cluster in the private subnets and bastion servers to access the cluster using the AWS EKS Module. 94 | 95 | - On line 14, the AutoScaling group configuration contains three nodes. 96 | 97 | - outputs.tf defines the output configuration. 98 | 99 | - versions.tf sets the Terraform version to at least 0.12. It also sets versions for the providers used in this sample. 100 | 101 | ## Initialize Terraform workspace 102 | 103 | 104 | ``` 105 | [Captains-Bay]🚩 > terraform init 106 | Initializing modules... 107 | Downloading terraform-aws-modules/eks/aws 12.0.0 for eks... 108 | - eks in .terraform/modules/eks/terraform-aws-eks-12.0.0 109 | - eks.node_groups in .terraform/modules/eks/terraform-aws-eks-12.0.0/modules/node_groups 110 | Downloading terraform-aws-modules/vpc/aws 2.6.0 for vpc... 111 | - vpc in .terraform/modules/vpc/terraform-aws-vpc-2.6.0 112 | 113 | Initializing the backend... 114 | 115 | Initializing provider plugins... 116 | - Checking for available provider plugins... 117 | - Downloading plugin for provider "random" (hashicorp/random) 2.2.1... 118 | - Downloading plugin for provider "local" (hashicorp/local) 1.4.0... 119 | - Downloading plugin for provider "null" (hashicorp/null) 2.1.2... 120 | - Downloading plugin for provider "kubernetes" (hashicorp/kubernetes) 1.11.3... 121 | - Downloading plugin for provider "template" (hashicorp/template) 2.1.2... 122 | - Downloading plugin for provider "aws" (hashicorp/aws) 2.64.0... 123 | 124 | Terraform has been successfully initialized! 125 | 126 | You may now begin working with Terraform. Try running "terraform plan" to see 127 | any changes that are required for your infrastructure. All Terraform commands 128 | should now work. 129 | 130 | If you ever set or change modules or backend configuration for Terraform, 131 | rerun this command to reinitialize your working directory. If you forget, other 132 | commands will detect it and remind you to do so if necessary. 133 | [Captains-Bay]🚩 > 134 | ``` 135 | 136 | ``` 137 | Apply complete! Resources: 51 added, 0 changed, 0 destroyed. 138 | 139 | Outputs: 140 | 141 | cluster_endpoint = https://83AEAE7D9A99A68DFA4162E18F4AD470.gr7.us-east-2.eks.amazonaws.com 142 | cluster_name = training-eks-9Vir2IUu 143 | cluster_security_group_id = sg-000e8af737c088047 144 | kubectl_config = apiVersion: v1 145 | preferences: {} 146 | kind: Config 147 | 148 | clusters: 149 | - cluster: 150 | server: https://83AEAE7D9A99A68DFA4162E18F4AD470.gr7.us-east-2.eks.amazonaws.com 151 | certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01EVXpNVEV5TWpNME1Wb1hEVE13TURVeU9URXlNak0wTVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFXXXXXXXXXXXXcEN2c1ZmanlkYmYxdGVmV0hXRXhsZ1prL01TSEt4R3BWdGthTFFvZ0NUVE51dzV1SzZNQ2FBM3FoeVNOTXMKc1pLVGMxSXhRQnNWdFVvZjRPNHhGZnd0aHM0Vk9zVEZmSEY4bHdnSnpwWEVEanlhRTJ1MnV4OHVnUnN1Y3RhMQpNWkFneVVBS1hma1pQV2d4OXBWdWFOMHkzeE02ZTdTaUtYNFpTNmhFQzcyK1hrK29Na2tsSlFlQ0J3TT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= 152 | name: eks_training-eks-9Vir2IUu 153 | 154 | contexts: 155 | - context: 156 | cluster: eks_training-eks-9Vir2IUu 157 | user: eks_training-eks-9Vir2IUu 158 | name: eks_training-eks-9Vir2IUu 159 | 160 | current-context: eks_training-eks-9Vir2IUu 161 | 162 | users: 163 | - name: eks_training-eks-9Vir2IUu 164 | user: 165 | exec: 166 | apiVersion: client.authentication.k8s.io/v1alpha1 167 | command: aws-iam-authenticator 168 | args: 169 | - "token" 170 | - "-i" 171 | - "training-eks-9Vir2IUu" 172 | region = us-east-2 173 | ``` 174 | 175 | ## Configure kubectl 176 | 177 | Now that you've provisioned your EKS cluster, you need to configure kubectl. Customize the following command with your cluster name and region, the values from Terraform's output. It will get the access credentials for your cluster and automatically configure kubectl. 178 | 179 | 180 | ``` 181 | aws eks --region us-east-2 update-kubeconfig --name training-eks-9Vir2IUu 182 | ``` 183 | 184 | ``` 185 | Added new context arn:aws:eks:us-east-2:125346028423:cluster/training-eks-9Vir2IUu to /Users/ajeetraina/.kube/ 186 | ``` 187 | 188 | 189 | ## Troubleshooting: 190 | 191 | If you are facing the below error message while running ```terraform init```: 192 | 193 | ``` 194 | [Captains-Bay]🚩 > terraform validate 195 | 196 | Error: Error parsing /Users/ajeetraina/.aws/learn-terraform-provision-eks-cluster/eks-cluster.tf: At 3:18: Unknown token: 3:18 IDENT local.cluster_name 197 | ``` 198 | 199 | Then to fix it , you need to update your Terraform version by running 200 | 201 | ``` 202 | brew upgrade terraform 203 | ``` 204 | 205 | 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /beginners/aws/eks/eks-cluster.tf: -------------------------------------------------------------------------------- 1 | module "eks" { 2 | source = "terraform-aws-modules/eks/aws" 3 | cluster_name = local.cluster_name 4 | subnets = module.vpc.private_subnets 5 | 6 | tags = { 7 | Environment = "training" 8 | GithubRepo = "terraform-aws-eks" 9 | GithubOrg = "terraform-aws-modules" 10 | } 11 | 12 | vpc_id = module.vpc.vpc_id 13 | 14 | worker_groups = [ 15 | { 16 | name = "worker-group-1" 17 | instance_type = "t2.small" 18 | additional_userdata = "echo foo bar" 19 | asg_desired_capacity = 2 20 | additional_security_group_ids = [aws_security_group.worker_group_mgmt_one.id] 21 | }, 22 | { 23 | name = "worker-group-2" 24 | instance_type = "t2.medium" 25 | additional_userdata = "echo foo bar" 26 | additional_security_group_ids = [aws_security_group.worker_group_mgmt_two.id] 27 | asg_desired_capacity = 1 28 | }, 29 | ] 30 | } 31 | 32 | data "aws_eks_cluster" "cluster" { 33 | name = module.eks.cluster_id 34 | } 35 | 36 | data "aws_eks_cluster_auth" "cluster" { 37 | name = module.eks.cluster_id 38 | } 39 | -------------------------------------------------------------------------------- /beginners/aws/eks/kubernetes-dashboard-admin.rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: admin-user 5 | namespace: kube-system 6 | --- 7 | # Create ClusterRoleBinding 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRoleBinding 10 | metadata: 11 | name: admin-user 12 | roleRef: 13 | apiGroup: rbac.authorization.k8s.io 14 | kind: ClusterRole 15 | name: cluster-admin 16 | subjects: 17 | - kind: ServiceAccount 18 | name: admin-user 19 | namespace: kube-system 20 | -------------------------------------------------------------------------------- /beginners/aws/eks/outputs.tf: -------------------------------------------------------------------------------- 1 | output "cluster_endpoint" { 2 | description = "Endpoint for EKS control plane." 3 | value = module.eks.cluster_endpoint 4 | } 5 | 6 | output "cluster_security_group_id" { 7 | description = "Security group ids attached to the cluster control plane." 8 | value = module.eks.cluster_security_group_id 9 | } 10 | 11 | output "kubectl_config" { 12 | description = "kubectl config as generated by the module." 13 | value = module.eks.kubeconfig 14 | } 15 | 16 | # output "config_map_aws_auth" { 17 | # description = "A kubernetes configuration to authenticate to this EKS cluster." 18 | # value = module.eks.config_map_aws_auth 19 | # } 20 | 21 | output "region" { 22 | description = "AWS region" 23 | value = var.region 24 | } 25 | 26 | output "cluster_name" { 27 | description = "Kubernetes Cluster Name" 28 | value = local.cluster_name 29 | } 30 | -------------------------------------------------------------------------------- /beginners/aws/eks/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | profile = "default" 3 | region = "us-east-2" 4 | } 5 | -------------------------------------------------------------------------------- /beginners/aws/eks/security-groups.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "worker_group_mgmt_one" { 2 | name_prefix = "worker_group_mgmt_one" 3 | vpc_id = module.vpc.vpc_id 4 | 5 | ingress { 6 | from_port = 22 7 | to_port = 22 8 | protocol = "tcp" 9 | 10 | cidr_blocks = [ 11 | "10.0.0.0/8", 12 | ] 13 | } 14 | } 15 | 16 | resource "aws_security_group" "worker_group_mgmt_two" { 17 | name_prefix = "worker_group_mgmt_two" 18 | vpc_id = module.vpc.vpc_id 19 | 20 | ingress { 21 | from_port = 22 22 | to_port = 22 23 | protocol = "tcp" 24 | 25 | cidr_blocks = [ 26 | "192.168.0.0/16", 27 | ] 28 | } 29 | } 30 | 31 | resource "aws_security_group" "all_worker_mgmt" { 32 | name_prefix = "all_worker_management" 33 | vpc_id = module.vpc.vpc_id 34 | 35 | ingress { 36 | from_port = 22 37 | to_port = 22 38 | protocol = "tcp" 39 | 40 | cidr_blocks = [ 41 | "10.0.0.0/8", 42 | "172.16.0.0/12", 43 | "192.168.0.0/16", 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /beginners/aws/eks/versions.tf: -------------------------------------------------------------------------------- 1 | 2 | terraform { 3 | required_version = ">= 0.12" 4 | } 5 | 6 | provider "random" { 7 | version = "~> 2.1" 8 | } 9 | 10 | provider "local" { 11 | version = "~> 1.2" 12 | } 13 | 14 | provider "null" { 15 | version = "~> 2.1" 16 | } 17 | 18 | provider "template" { 19 | version = "~> 2.1" 20 | } 21 | -------------------------------------------------------------------------------- /beginners/aws/eks/vpc.tf: -------------------------------------------------------------------------------- 1 | variable "region" { 2 | default = "us-east-2" 3 | description = "AWS region" 4 | } 5 | 6 | provider "aws" { 7 | version = ">= 2.28.1" 8 | region = "us-east-2" 9 | } 10 | 11 | data "aws_availability_zones" "available" {} 12 | 13 | locals { 14 | cluster_name = "training-eks-${random_string.suffix.result}" 15 | } 16 | 17 | resource "random_string" "suffix" { 18 | length = 8 19 | special = false 20 | } 21 | 22 | module "vpc" { 23 | source = "terraform-aws-modules/vpc/aws" 24 | version = "2.6.0" 25 | 26 | name = "training-vpc" 27 | cidr = "10.0.0.0/16" 28 | azs = data.aws_availability_zones.available.names 29 | private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] 30 | public_subnets = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"] 31 | enable_nat_gateway = true 32 | single_nat_gateway = true 33 | enable_dns_hostnames = true 34 | 35 | tags = { 36 | "kubernetes.io/cluster/${local.cluster_name}" = "shared" 37 | } 38 | 39 | public_subnet_tags = { 40 | "kubernetes.io/cluster/${local.cluster_name}" = "shared" 41 | "kubernetes.io/role/elb" = "1" 42 | } 43 | 44 | private_subnet_tags = { 45 | "kubernetes.io/cluster/${local.cluster_name}" = "shared" 46 | "kubernetes.io/role/internal-elb" = "1" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /beginners/aws/main.tf: -------------------------------------------------------------------------------- 1 | module "collabnix_vpc" { 2 | source = "./modules/vpc" 3 | } 4 | 5 | module "collabnix_ec2" { 6 | source = "./modules/ec2" 7 | public_subnet = module.collabnix_vpc.public_subnet_id 8 | } 9 | 10 | module "collabnix_ec2_webserver" { 11 | source = "./modules/ec2_apache_webserver" 12 | public_subnet = module.collabnix_vpc.public_subnet_id 13 | } 14 | 15 | module "collabnix_static_s3_website" { 16 | source = "./modules/s3" 17 | s3_bucket_name = "my-collabnix-test-bucket-name.com" 18 | aws_profile_name = "{profile_name}" 19 | document_directory = "./modules/s3/" 20 | } 21 | 22 | module "collabnix_application_load_balancer" { 23 | source = "./modules/application_load_balancer" 24 | } 25 | 26 | module "collabnix_API_Gateway_Cloudwatch" { 27 | source = "./modules/API_Gateway & Cloudwatch" 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /beginners/aws/modules/API_Gateway & CloudWatch/CloudWatch_dashboard.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_dashboard" "main" { 2 | dashboard_name = "test-d" 3 | 4 | dashboard_body = < 59 | 60 | $inputRoot.body 61 | 62 | EOF 63 | } 64 | } 65 | resource "aws_api_gateway_deployment" "panda1" { 66 | rest_api_id = aws_api_gateway_rest_api.panda.id 67 | 68 | triggers = { 69 | 70 | redeployment = sha1(jsonencode([ 71 | aws_api_gateway_resource.healthcheck.id, 72 | aws_api_gateway_method.panda1.id, 73 | aws_api_gateway_integration.integration.id, 74 | ])) 75 | } 76 | 77 | lifecycle { 78 | create_before_destroy = true 79 | } 80 | } 81 | 82 | resource "aws_api_gateway_resource" "panda" { 83 | parent_id = aws_api_gateway_rest_api.panda.root_resource_id 84 | path_part = "panda" 85 | rest_api_id = aws_api_gateway_rest_api.panda.id 86 | } 87 | 88 | resource "aws_api_gateway_method" "panda" { 89 | authorization = "NONE" 90 | http_method = "GET" 91 | resource_id = aws_api_gateway_resource.panda.id 92 | rest_api_id = aws_api_gateway_rest_api.panda.id 93 | } 94 | resource "aws_api_gateway_integration" "panda" { 95 | http_method = aws_api_gateway_method.panda.http_method 96 | resource_id = aws_api_gateway_resource.panda.id 97 | rest_api_id = aws_api_gateway_rest_api.panda.id 98 | type = "MOCK" 99 | } 100 | 101 | 102 | 103 | resource "aws_api_gateway_deployment" "panda" { 104 | rest_api_id = aws_api_gateway_rest_api.panda.id 105 | 106 | triggers = { 107 | 108 | redeployment = sha1(jsonencode([ 109 | aws_api_gateway_resource.panda.id, 110 | aws_api_gateway_method.panda.id, 111 | aws_api_gateway_integration.panda.id, 112 | ])) 113 | } 114 | 115 | lifecycle { 116 | create_before_destroy = true 117 | } 118 | } 119 | 120 | resource "aws_api_gateway_stage" "panda" { 121 | depends_on = [aws_api_gateway_deployment.panda1, aws_api_gateway_stage.panda] 122 | deployment_id = aws_api_gateway_deployment.panda.id 123 | rest_api_id = aws_api_gateway_rest_api.panda.id 124 | stage_name = "panda" 125 | } 126 | 127 | -------------------------------------------------------------------------------- /beginners/aws/modules/API_Gateway & CloudWatch/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "Enter_Region" 3 | access_key = "Enter_Access_Key" 4 | secret_key = "Enter_Secret_Key" 5 | } 6 | -------------------------------------------------------------------------------- /beginners/aws/modules/API_Gateway & CloudWatch/route53_health_check.tf: -------------------------------------------------------------------------------- 1 | resource "aws_sns_topic" "sns" { 2 | name = "user-updates-topic" 3 | } 4 | 5 | locals { 6 | rest_api_id = aws_api_gateway_rest_api.panda.id 7 | } 8 | 9 | output "rest_api_id" { 10 | value = local.rest_api_id 11 | } 12 | 13 | resource "aws_route53_health_check" "http" { 14 | fqdn = format("%s.%s",aws_api_gateway_rest_api.panda.id,"execute-api.enter_region.amazonaws.com") 15 | insufficient_data_health_status = "Healthy" 16 | port = 443 17 | type = "HTTPS" 18 | resource_path = "/" 19 | failure_threshold = "3" 20 | request_interval = "30" 21 | 22 | tags = { 23 | Name = "api-health-check" 24 | } 25 | } 26 | resource "aws_cloudwatch_metric_alarm" "http1" { 27 | depends_on = [aws_route53_health_check.http] 28 | alarm_name = "foobar" 29 | comparison_operator = "LessThanThreshold" 30 | evaluation_periods = "1" 31 | metric_name = "HealthCheckStatus" 32 | namespace = "AWS/Route53" 33 | period = "60" 34 | statistic = "Minimum" 35 | alarm_description = "This metric monitors ec2 cpu utilization" 36 | actions_enabled = "true" 37 | alarm_actions = [aws_sns_topic.sns.arn] 38 | ok_actions = [aws_sns_topic.sns.arn] 39 | 40 | dimensions = { 41 | HealthCheckName = "api-health-check" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /beginners/aws/modules/API_Gateway & CloudWatch/var.json.tf: -------------------------------------------------------------------------------- 1 | { 2 | "variable": { 3 | "example": { 4 | "default": "panda" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /beginners/aws/modules/application_load_balancer/README.md: -------------------------------------------------------------------------------- 1 | # application_load_balancer 2 | 3 | These templates implements a application load balancer, and associated necessary steps require for loadbalancing. We used below services : 4 | 5 | - Security groups for instances and loadbalancer 6 | - Target grout attachment for instances 7 | - Template for launching instances 8 | - Load balancer 9 | 10 | 11 | -- Mention your region, secret and access keys, vpc_id, subnet_ids and ami_id required in the templates. 12 | 13 | To run these templates, clone the repository and run `terraform apply` within its own directory. 14 | 15 | For example: 16 | 17 | ```tf 18 | $ git clone https://github.com/collabnix/terraform.git 19 | $ cd terraform/beginner/aws/modules/application_load_balancer 20 | $ terraform apply 21 | ``` 22 | -------------------------------------------------------------------------------- /beginners/aws/modules/application_load_balancer/instances.tf: -------------------------------------------------------------------------------- 1 | resource "aws_instance" "web1" { 2 | ami = "enter-ami-id" 3 | instance_type = "t2.micro" 4 | subnet_id = "enter-subnet-id" 5 | vpc_security_group_ids = [aws_security_group.allow_http_instances.id] 6 | key_name = "enter-key-name" 7 | provisioner "remote-exec" { 8 | inline = [ 9 | "sudo yum install httpd -y", 10 | "sudo service httpd start", 11 | "sudo chkconfig httpd on" 12 | ] 13 | 14 | connection { 15 | type = "ssh" 16 | user = "ec2-user" 17 | host = aws_instance.web.public_ip 18 | private_key = file("${path.module}/key-name.pem") 19 | } 20 | 21 | } 22 | } 23 | 24 | resource "aws_instance" "web2" { 25 | ami = "enter-ami-id" 26 | instance_type = "t2.micro" 27 | subnet_id = "enter-your-subnet-id" 28 | vpc_security_group_ids = [aws_security_group.allow_http_instances.id] 29 | key_name = "enter-key-name" 30 | provisioner "remote-exec" { 31 | inline = [ 32 | "sudo yum install https -y", 33 | "sudo service httpd start", 34 | "sudo chkconfig httpd on" 35 | ] 36 | 37 | connection { 38 | type = "ssh" 39 | user = "ec2-user" 40 | host = aws_instance.web2.public_ip 41 | private_key = file("${path.module}/kay-name.pem") 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /beginners/aws/modules/application_load_balancer/loadbalancer.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb" "my-lb" { 2 | name = "lb-tf" 3 | internal = false 4 | load_balancer_type = "application" 5 | security_groups = [aws_security_group.allow_http.id] 6 | # Enter you subnet ids under vpc below 7 | subnets = ["subnet-id1","subnet-id2","subnet-id3","subnet-id4"] 8 | 9 | enable_deletion_protection = false 10 | 11 | 12 | 13 | tags = { 14 | name = "my-first-load-balancer" 15 | } 16 | } 17 | 18 | resource "aws_lb_listener" "front_end" { 19 | load_balancer_arn = aws_lb.my-lb.arn 20 | port = "80" 21 | protocol = "HTTP" 22 | 23 | default_action { 24 | type = "forward" 25 | target_group_arn = aws_lb_target_group.target-lb.arn 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /beginners/aws/modules/application_load_balancer/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "Enter_Region" 3 | access_key = "Enter_Access_Key" 4 | secret_key = "Enter_Secret_Key" 5 | } 6 | -------------------------------------------------------------------------------- /beginners/aws/modules/application_load_balancer/security_group.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "allow_http" { 2 | name = "alb_http" 3 | description = "Allow http traffic to alb" 4 | vpc_id = "enter_vpc_id" 5 | 6 | ingress { 7 | description = "http for alb" 8 | from_port = 80 9 | to_port = 80 10 | protocol = "tcp" 11 | cidr_blocks = ["0.0.0.0/0"] 12 | } 13 | 14 | egress { 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 = "allow_http_alb" 23 | } 24 | } 25 | 26 | resource "aws_security_group" "allow_http_instances" { 27 | name = "instances_http" 28 | description = "Allow http traffic to instances" 29 | vpc_id = "enter_vpc_id" 30 | 31 | ingress { 32 | description = "http for instances" 33 | from_port = 80 34 | to_port = 80 35 | protocol = "tcp" 36 | security_groups = [aws_security_group.allow_http.id] 37 | } 38 | 39 | ingress { 40 | description = "ssh for instances" 41 | from_port = 22 42 | to_port = 22 43 | protocol = "tcp" 44 | cidr_blocks = ["0.0.0.0/0"] 45 | } 46 | egress { 47 | from_port = 0 48 | to_port = 0 49 | protocol = "-1" 50 | cidr_blocks = ["0.0.0.0/0"] 51 | } 52 | 53 | tags = { 54 | Name = "allow_http_instaces" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /beginners/aws/modules/application_load_balancer/target_group_attach.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_target_group" "target-lb" { 2 | name = "lb-tg" 3 | port = 80 4 | protocol = "HTTP" 5 | vpc_id = "enter_vpc_id" 6 | } 7 | resource "aws_lb_target_group_attachment" "test1" { 8 | target_group_arn = aws_lb_target_group.target-lb.arn 9 | target_id = aws_instance.web1.id 10 | port = 80 11 | } 12 | resource "aws_lb_target_group_attachment" "test2" { 13 | target_group_arn = aws_lb_target_group.target-lb.arn 14 | target_id = aws_instance.web2.id 15 | port = 80 16 | } 17 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2/ec2.tf: -------------------------------------------------------------------------------- 1 | data "aws_ami" "ubuntu" { 2 | most_recent = true 3 | 4 | filter { 5 | name = "name" 6 | values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server*"] 7 | } 8 | 9 | filter { 10 | name = "virtualization-type" 11 | values = ["hvm"] 12 | } 13 | 14 | owners = ["099720109477"] # Canonical 15 | } 16 | 17 | resource "aws_instance" "instance" { 18 | ami = data.aws_ami.ubuntu.id 19 | instance_type = "t2.micro" 20 | key_name = var.key_pair_name 21 | 22 | network_interface { 23 | network_interface_id = aws_network_interface.defaultNIC.id 24 | device_index = 0 25 | } 26 | 27 | tags = { 28 | project = "Collabnix" 29 | department = "Automation" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAyjNZt4CEVPBtDvKDlDfCvYvaldg1uivuPzP45nWKuA9edKAe 3 | AxWsnAkIVY2LDzU7Dwgmi7pv3ZoIfZycN1xpDA864N/iSsBZbcT7ViHedKWZVW1V 4 | 3ahIihO4zAL3ZEtw9e3t3GfoSdtT+0q5y27DRrN5UXDoX2k8GbD7oldmGbkoo3LJ 5 | gp6tnckbEAqsSfbSpIWS/x/x5Z8BBkibrt6O+oJFnR720j6SSUNlvqQceeAlJqUi 6 | hTlE2MjrcPWVwdI9D4YCpVr9uqdSAAWaHcRcWYokYNGTq2CjMiPbmENYXCM3KrbL 7 | GDIFym0eSWz86Pktnn+g22UHir0/6ugLCh+hrwIDAQABAoIBAE3zJ+YfLGTWXyTB 8 | B0qviGqsLLNRq7y+zNUewxiNPdIhUqehRpCn3Wg17zmUHITbX4429S0uzYtfo2BR 9 | bMPG41Rb1rX0eXeZ2aAArWgSHIFZidguE0klY/mfCsHTbu4CS2TzuZwbjqhSXnjk 10 | 4OV1KODrtZxY66xElH/PA+Mc0GaflBbK54KxCAUSbEAJHAkizgpCXRLrsDe4SZW8 11 | YtrEd6M5d/ZlICL+pLG0EnNYuVziNEfECKXPf58M+JM3kQjCdRniZU+4EqGSv84D 12 | 7TRsJepbKdVuoUFu95iJ0bmdOM34aZOI70+38yLCMMm1eAaBkM5NxE9/q7IH8cBM 13 | eYnF4DkCgYEA9ElIj94j/vbOrOXP6//x7b+AMIEyqInjEWh8W49/NRbQoM0e7tM6 14 | EiB282Cfp0R5mrEPlDcyVurFTQXAbkgcICPwX2AQyZOxaoJX9341jWxkd9i1TNm5 15 | kwL1AwIaeVpVc0jpHXJgS3wewoJOeICRMm6vHu3JVo69gTk3oAXEAq0CgYEA0+Vy 16 | mWZM1c217kRG2UYMe01cxmV6t0XIJIdQXQd/LwLr54GxzV4lBO7xob426TXkLFkb 17 | wgXsCxNd9GbuJHZ2xolS30O8VW5kOV/zsy0oQ1WqAPNPAOneAxFO0mQitM2HC1PX 18 | McKQEezl7SvioEsBanlxNuIrLVMP2QlQQujiXUsCgYEAxFzD/yFJPgGWUFTKtaGf 19 | DsUIffTci62K4MtkaxUF497bBObdHoyb+UYvV6MrsoDQXxBEvZdA160Pu8IL1JoS 20 | QaOh7IiD9gTKcBsmKsNAuNWQTOXdllDNYubVm/1s2m9KkMji2dC+pu62qxOjkCmI 21 | jUl7axko5nMG0YD0vaTk0mECgYAiXocWBpfT3gfyW7S6LTh9D3FK5M7gxzrNYf1Q 22 | +ZRRhcHJzSmPzANpJ3Cd8YJqlUkrQFDWSaudqEiHCeL6mxRs431DpXL40G0FOWEH 23 | 4P003sIyYUShO029ZaNJUOCoPuX2mmS/N3Wy0qAAtiuOIFxcbtJEOq8SLPTXGUGh 24 | eLCuvQKBgAUEk0iLv0S53yen7QfoheO94rWRPVXRqrXpzdkpqbgn2AloBxVH4SYj 25 | UN2rgN8V2iEXypngk/t2sgi1MK4BP2BG1jGdSz4lUIvgGSw0i75Pir2/mzQZ0zms 26 | IMW9toZlaAIRESv4OnlkngcEdRBF9v6Koui0zxCD6tt2wVs/LCyc 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2/keypair.tf: -------------------------------------------------------------------------------- 1 | resource "aws_key_pair" "keypair" { 2 | key_name = var.key_pair_name 3 | public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKM1m3gIRU8G0O8oOUN8K9i9qV2DW6K+4/M/jmdYq4D150oB4DFaycCQhVjYsPNTsPCCaLum/dmgh9nJw3XGkMDzrg3+JKwFltxPtWId50pZlVbVXdqEiKE7jMAvdkS3D17e3cZ+hJ21P7SrnLbsNGs3lRcOhfaTwZsPuiV2YZuSijcsmCnq2dyRsQCqxJ9tKkhZL/H/HlnwEGSJuu3o76gkWdHvbSPpJJQ2W+pBx54CUmpSKFOUTYyOtw9ZXB0j0PhgKlWv26p1IABZodxFxZiiRg0ZOrYKMyI9uYQ1hcIzcqtssYMgXKbR5JbPzo+S2ef6DbZQeKvT/q6AsKH6Gv" 4 | } 5 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2/networkinterface.tf: -------------------------------------------------------------------------------- 1 | resource "aws_network_interface" "defaultNIC" { 2 | subnet_id = var.public_subnet 3 | 4 | tags = { 5 | project = "Collabnix" 6 | department = "Automation" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2/outputs.tf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/beginners/aws/modules/ec2/outputs.tf -------------------------------------------------------------------------------- /beginners/aws/modules/ec2/public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyjNZt4CEVPBtDvKDlDfC 3 | vYvaldg1uivuPzP45nWKuA9edKAeAxWsnAkIVY2LDzU7Dwgmi7pv3ZoIfZycN1xp 4 | DA864N/iSsBZbcT7ViHedKWZVW1V3ahIihO4zAL3ZEtw9e3t3GfoSdtT+0q5y27D 5 | RrN5UXDoX2k8GbD7oldmGbkoo3LJgp6tnckbEAqsSfbSpIWS/x/x5Z8BBkibrt6O 6 | +oJFnR720j6SSUNlvqQceeAlJqUihTlE2MjrcPWVwdI9D4YCpVr9uqdSAAWaHcRc 7 | WYokYNGTq2CjMiPbmENYXCM3KrbLGDIFym0eSWz86Pktnn+g22UHir0/6ugLCh+h 8 | rwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2/variables.tf: -------------------------------------------------------------------------------- 1 | variable "public_subnet" {} 2 | 3 | variable "key_pair_name" { 4 | description = "Key_Pair_Name" 5 | type = string 6 | default = "keypair" 7 | } 8 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2_apache_webserver/bootscript.sh: -------------------------------------------------------------------------------- 1 | !/bin/bash 2 | 3 | sudo apt-get update -y 4 | 5 | sudo apt install apache2 -y -------------------------------------------------------------------------------- /beginners/aws/modules/ec2_apache_webserver/ec2.tf: -------------------------------------------------------------------------------- 1 | data "aws_ami" "ubuntu" { 2 | most_recent = true 3 | 4 | filter { 5 | name = "name" 6 | values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server*"] 7 | } 8 | 9 | filter { 10 | name = "virtualization-type" 11 | values = ["hvm"] 12 | } 13 | 14 | owners = ["099720109477"] # Canonical 15 | } 16 | 17 | resource "aws_instance" "webserver" { 18 | ami = data.aws_ami.ubuntu.id 19 | instance_type = "t2.micro" 20 | key_name = var.key_pair_name 21 | 22 | network_interface { 23 | network_interface_id = aws_network_interface.webserverNIC.id 24 | device_index = 0 25 | } 26 | 27 | provisioner "file" { 28 | 29 | connection { 30 | host = self.public_ip 31 | type = "ssh" 32 | user = "ubuntu" 33 | private_key = file("${path.module}/key.pem") 34 | } 35 | 36 | source = var.bootscript_file_path 37 | destination = "/tmp/bootscript.sh" 38 | } 39 | 40 | provisioner "remote-exec" { 41 | 42 | connection { 43 | host = self.public_ip 44 | type = "ssh" 45 | user = "ubuntu" 46 | private_key = file("${path.module}/key.pem") 47 | } 48 | inline = [ 49 | "chmod +x /tmp/bootscript.sh", 50 | "/tmp/bootscript.sh", 51 | ] 52 | } 53 | 54 | tags = { 55 | project = "Collabnix" 56 | department = "Automation" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2_apache_webserver/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAyjNZt4CEVPBtDvKDlDfCvYvaldg1uivuPzP45nWKuA9edKAe 3 | AxWsnAkIVY2LDzU7Dwgmi7pv3ZoIfZycN1xpDA864N/iSsBZbcT7ViHedKWZVW1V 4 | 3ahIihO4zAL3ZEtw9e3t3GfoSdtT+0q5y27DRrN5UXDoX2k8GbD7oldmGbkoo3LJ 5 | gp6tnckbEAqsSfbSpIWS/x/x5Z8BBkibrt6O+oJFnR720j6SSUNlvqQceeAlJqUi 6 | hTlE2MjrcPWVwdI9D4YCpVr9uqdSAAWaHcRcWYokYNGTq2CjMiPbmENYXCM3KrbL 7 | GDIFym0eSWz86Pktnn+g22UHir0/6ugLCh+hrwIDAQABAoIBAE3zJ+YfLGTWXyTB 8 | B0qviGqsLLNRq7y+zNUewxiNPdIhUqehRpCn3Wg17zmUHITbX4429S0uzYtfo2BR 9 | bMPG41Rb1rX0eXeZ2aAArWgSHIFZidguE0klY/mfCsHTbu4CS2TzuZwbjqhSXnjk 10 | 4OV1KODrtZxY66xElH/PA+Mc0GaflBbK54KxCAUSbEAJHAkizgpCXRLrsDe4SZW8 11 | YtrEd6M5d/ZlICL+pLG0EnNYuVziNEfECKXPf58M+JM3kQjCdRniZU+4EqGSv84D 12 | 7TRsJepbKdVuoUFu95iJ0bmdOM34aZOI70+38yLCMMm1eAaBkM5NxE9/q7IH8cBM 13 | eYnF4DkCgYEA9ElIj94j/vbOrOXP6//x7b+AMIEyqInjEWh8W49/NRbQoM0e7tM6 14 | EiB282Cfp0R5mrEPlDcyVurFTQXAbkgcICPwX2AQyZOxaoJX9341jWxkd9i1TNm5 15 | kwL1AwIaeVpVc0jpHXJgS3wewoJOeICRMm6vHu3JVo69gTk3oAXEAq0CgYEA0+Vy 16 | mWZM1c217kRG2UYMe01cxmV6t0XIJIdQXQd/LwLr54GxzV4lBO7xob426TXkLFkb 17 | wgXsCxNd9GbuJHZ2xolS30O8VW5kOV/zsy0oQ1WqAPNPAOneAxFO0mQitM2HC1PX 18 | McKQEezl7SvioEsBanlxNuIrLVMP2QlQQujiXUsCgYEAxFzD/yFJPgGWUFTKtaGf 19 | DsUIffTci62K4MtkaxUF497bBObdHoyb+UYvV6MrsoDQXxBEvZdA160Pu8IL1JoS 20 | QaOh7IiD9gTKcBsmKsNAuNWQTOXdllDNYubVm/1s2m9KkMji2dC+pu62qxOjkCmI 21 | jUl7axko5nMG0YD0vaTk0mECgYAiXocWBpfT3gfyW7S6LTh9D3FK5M7gxzrNYf1Q 22 | +ZRRhcHJzSmPzANpJ3Cd8YJqlUkrQFDWSaudqEiHCeL6mxRs431DpXL40G0FOWEH 23 | 4P003sIyYUShO029ZaNJUOCoPuX2mmS/N3Wy0qAAtiuOIFxcbtJEOq8SLPTXGUGh 24 | eLCuvQKBgAUEk0iLv0S53yen7QfoheO94rWRPVXRqrXpzdkpqbgn2AloBxVH4SYj 25 | UN2rgN8V2iEXypngk/t2sgi1MK4BP2BG1jGdSz4lUIvgGSw0i75Pir2/mzQZ0zms 26 | IMW9toZlaAIRESv4OnlkngcEdRBF9v6Koui0zxCD6tt2wVs/LCyc 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2_apache_webserver/keypair.tf: -------------------------------------------------------------------------------- 1 | resource "aws_key_pair" "webserver_keypair" { 2 | key_name = var.key_pair_name 3 | public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKM1m3gIRU8G0O8oOUN8K9i9qV2DW6K+4/M/jmdYq4D150oB4DFaycCQhVjYsPNTsPCCaLum/dmgh9nJw3XGkMDzrg3+JKwFltxPtWId50pZlVbVXdqEiKE7jMAvdkS3D17e3cZ+hJ21P7SrnLbsNGs3lRcOhfaTwZsPuiV2YZuSijcsmCnq2dyRsQCqxJ9tKkhZL/H/HlnwEGSJuu3o76gkWdHvbSPpJJQ2W+pBx54CUmpSKFOUTYyOtw9ZXB0j0PhgKlWv26p1IABZodxFxZiiRg0ZOrYKMyI9uYQ1hcIzcqtssYMgXKbR5JbPzo+S2ef6DbZQeKvT/q6AsKH6Gv" 4 | } 5 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2_apache_webserver/networkinterface.tf: -------------------------------------------------------------------------------- 1 | resource "aws_network_interface" "webserverNIC" { 2 | subnet_id = var.public_subnet 3 | 4 | tags = { 5 | project = "Collabnix" 6 | department = "Automation" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2_apache_webserver/outputs.tf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/beginners/aws/modules/ec2_apache_webserver/outputs.tf -------------------------------------------------------------------------------- /beginners/aws/modules/ec2_apache_webserver/public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyjNZt4CEVPBtDvKDlDfC 3 | vYvaldg1uivuPzP45nWKuA9edKAeAxWsnAkIVY2LDzU7Dwgmi7pv3ZoIfZycN1xp 4 | DA864N/iSsBZbcT7ViHedKWZVW1V3ahIihO4zAL3ZEtw9e3t3GfoSdtT+0q5y27D 5 | RrN5UXDoX2k8GbD7oldmGbkoo3LJgp6tnckbEAqsSfbSpIWS/x/x5Z8BBkibrt6O 6 | +oJFnR720j6SSUNlvqQceeAlJqUihTlE2MjrcPWVwdI9D4YCpVr9uqdSAAWaHcRc 7 | WYokYNGTq2CjMiPbmENYXCM3KrbLGDIFym0eSWz86Pktnn+g22UHir0/6ugLCh+h 8 | rwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /beginners/aws/modules/ec2_apache_webserver/variables.tf: -------------------------------------------------------------------------------- 1 | variable "public_subnet" {} 2 | 3 | variable "key_pair_name" { 4 | description = "Key_Pair_Name" 5 | type = string 6 | default = "webserver_keypair" 7 | } 8 | -------------------------------------------------------------------------------- /beginners/aws/modules/s3/README.md: -------------------------------------------------------------------------------- 1 | # Create a Static Website on AWS S3 account with Terraform 2 | 3 | **This module creates a S3 Bucket and hosts a static website** 4 | 5 | > Note 1: This deployment is not free. If you are not on a free trail, it will incur a very small fee. So, its always a good practice to cleanup everything when you are done with the demo. 6 | 7 | 8 | ## Prerequisites 9 | 10 | AWS Account 11 | 12 | ## Start this module 13 | 14 | 15 | > Make sure you are in directory outside modules and running terraform command as the user who has AWS s3 CLI permissions. 16 | > Please change below attributes as per your requirements s3_bucket_name, document_directory and aws_profile_name(this is AWS credentials profile name) in module section. 17 | > This will create S3 bucket and followed by it will upload sample HTML files into the bucket. 18 | > Execute above command sudo **$ sudo terraform apply -target module.collabnix_static_s3_website -auto-approve** 19 | - After the S3 bucket created, copy the url from the output, paste it in a browser. You should see the below page 20 | 21 | 22 | 23 | ![Success](https://github.com/collabnix/terraform/blob/master/images/aws_website_success.png) 24 | 25 | - If you want to see the error page, append /error to the url. 26 | 27 | 28 | 29 | ![Error](https://github.com/collabnix/terraform/blob/master/images/aws_website_error.png) 30 | 31 | 32 | ## After the deployment 33 | 34 | - Cleanup everything with **$ sudo terraform destroy -target module.collabnix_static_s3_website -auto-approve** 35 | -------------------------------------------------------------------------------- /beginners/aws/modules/s3/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

OPPS SOMETHING WENT WRONG, THE PAGE YOU HAVE REQUESTED DOESN'T EXIST

4 | 5 | 6 | -------------------------------------------------------------------------------- /beginners/aws/modules/s3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

WELCOME TO YOUR STATIC WEBSITE

4 | 5 | 6 | -------------------------------------------------------------------------------- /beginners/aws/modules/s3/outputs.tf: -------------------------------------------------------------------------------- 1 | output "bucket_domain_name" { 2 | value = aws_s3_bucket.my_static_website_bucket.website_endpoint 3 | } 4 | 5 | output "this_s3_bucket_bucket_regional_domain_name" { 6 | description = "The bucket region-specific domain name. The bucket domain name including the region name, please refer here for format. Note: The AWS CloudFront allows specifying S3 region-specific endpoint when creating S3 origin, it will prevent redirect issues from CloudFront to S3 Origin URL." 7 | value = aws_s3_bucket.my_static_website_bucket.bucket_regional_domain_name 8 | } 9 | -------------------------------------------------------------------------------- /beginners/aws/modules/s3/s3.tf: -------------------------------------------------------------------------------- 1 | resource "aws_s3_bucket" "my_static_website_bucket" { 2 | bucket = var.s3_bucket_name 3 | acl = "public-read" 4 | force_destroy = true 5 | 6 | tags = { 7 | project = "Collabnix" 8 | department = "Automation" 9 | } 10 | 11 | website { 12 | index_document = "index.html" 13 | error_document = "error.html" 14 | 15 | routing_rules = < You can add the Service principal variables in **terraform.tfvars** file in the format shown below. 27 | 28 | *client_id = "CLIENTID-OF-THE-APP"\ 29 | client_secret = "CLIENT-SECRET-OF-THE-APP"\ 30 | subscription_id = "SUBSCRIPTIONID"\ 31 | tenant_id = "TENANTID"* 32 | 33 | **This is not a best practice. If you choose to do this, YOU MUST NOT CHECK THIS FILE INTO VERSION CONTROL. 34 | I would suggest you to add these as Environment variables. You can refer the terraform-azure authentication process documentation [here](https://www.terraform.io/docs/providers/azurerm/guides/service_principal_client_secret.html)** 35 | 36 | > You can also provide these credentials at the run time or you can supply the variables for terraform plan and terraform apply 37 | 38 | - *$ terraform plan -var "client_id=CLIENT_ID" -var "client_secret=CLIENT_SECRET" -var "subscription_id=SUBSCRIPTION_ID" -var "tenant_id=TENANT_ID" 39 | 40 | ### Run the terraform commands shown below 41 | 42 | 43 | - *$ terraform init* 44 | - *$ terraform validate* 45 | - *$ terraform plan -out=vnet.tfplan* 46 | - *$ terraform apply vnet.tfplan* 47 | 48 | > You have to manually type 'yes' to deploy the infrastructure. You can skip the manual intervention with the command **"terraform apply -auto-approve"** 49 | 50 | Once the deployment is done and you have verified the resources in the azure portal, cleanup everything with below command. 51 | 52 | - $ terraform destroy 53 | 54 | > Again, you have to manually type 'yes' to destroy the infrastructure. You can skip the manual intervention with the command **"terraform destroy -auto-approve"** -------------------------------------------------------------------------------- /beginners/azure/aks_cluster/README.md: -------------------------------------------------------------------------------- 1 | # Create a AKS Cluster with Container Monitoring enabled using Azure Terraform 2 | 3 | **This module creates a 3 node Linux AKS Cluster** 4 | 5 | > Note 1: This deployment is not free. If you are not on a free trail, it will incur a very small fee. So, its always a good practice to cleanup everything when you are done with the demo. 6 | 7 | > Note 2: We are creating a public IP address and attaching it to the AKS Cluster Load balancer. 8 | ## Resources in this module 9 | 10 | - A Resource Group 11 | - A Virtual network with a Subnet 12 | - A Network Security Group 13 | - Subnet and NSG Association 14 | - A Public IP Address 15 | - AKS Cluster 16 | - Route Tabels 17 | - Log Analytics Workspace 18 | - Container Monitoring Solution for Log Analytics 19 | 20 | > Notice that in this module, we are using a **Sufix** variable. We can use it to append to all resources for names. 21 | 22 | > Note 1 - This output the cluster key, certificate and the passwords 23 | 24 | ## Prerequisites 25 | 26 | Click [Here](https://github.com/collabnix/terraform/blob/master/beginners/azure/README.md) to know the process of initial set up. 27 | 28 | ## Steps 29 | 30 | - *$ cd beginners/azure/aks_cluster* 31 | 32 | > Make sure you are in this directory. This is the directory from where we run terraform commands. 33 | 34 | ## After the deployment 35 | 36 | - Once the deployment is successful, you can use **az login** to authenticate to subscription and use **az aks get-credentials** command with proper parameters to download the cluster credentials. 37 | 38 | - Cleanup everything with **$ terraform destroy -auto-approve** 39 | -------------------------------------------------------------------------------- /beginners/azure/aks_cluster/main.tf: -------------------------------------------------------------------------------- 1 | /* 2 | *Author - Kasun Rajapakse 3 | *Subject - Create AKS Cluster 4 | *Language - HCL 5 | */ 6 | 7 | #Add Azure Provider 8 | provider "azurerm" { 9 | 10 | version = "~>2.0" 11 | client_id = var.client_id 12 | client_secret = var.client_secret 13 | subscription_id = var.subscription_id 14 | tenant_id = var.tenant_id 15 | features {} 16 | } 17 | 18 | resource "random_string" "log_analytics_sufix" { 19 | length = 5 20 | lower = true 21 | special = false 22 | number = false 23 | } 24 | 25 | #Create Resource Group 26 | resource "azurerm_resource_group" "k8terraform" { 27 | name = var.resource_group_name 28 | location = var.location 29 | } 30 | 31 | #Create Log Analytics Workspace 32 | resource "azurerm_log_analytics_workspace" "aksterraform" { 33 | name = "${var.log_analytics_workspace_name}-${random_string.log_analytics_sufix.result}" 34 | location = var.log_analytics_workspace_location 35 | resource_group_name = azurerm_resource_group.k8terraform.name 36 | sku = var.log_analytics_workspace_sku 37 | } 38 | 39 | #Enable Log Analytics Solution 40 | resource "azurerm_log_analytics_solution" "aksterraformsolution" { 41 | solution_name = "ContainerInsights" 42 | location = azurerm_log_analytics_workspace.aksterraform.location 43 | resource_group_name = azurerm_resource_group.k8terraform.name 44 | workspace_resource_id = azurerm_log_analytics_workspace.aksterraform.id 45 | workspace_name = azurerm_log_analytics_workspace.aksterraform.name 46 | 47 | plan { 48 | publisher = "Microsoft" 49 | product = "OMSGallery/ContainerInsights" 50 | } 51 | } 52 | 53 | #Create AKS Cluster 54 | resource "azurerm_kubernetes_cluster" "k8cluster" { 55 | name = var.cluster_name 56 | location = azurerm_resource_group.k8terraform.location 57 | resource_group_name = azurerm_resource_group.k8terraform.name 58 | dns_prefix = var.dns_prifix 59 | 60 | default_node_pool { 61 | name = "infrapool" 62 | vm_size = "Standard_D2_v2" 63 | max_pods = 50 64 | node_count = 3 65 | } 66 | 67 | addon_profile{ 68 | oms_agent{ 69 | enabled = true 70 | log_analytics_workspace_id = azurerm_log_analytics_workspace.aksterraform.id 71 | } 72 | } 73 | 74 | identity { 75 | type = "SystemAssigned" 76 | } 77 | 78 | tags ={ 79 | Enviornment = "Development" 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /beginners/azure/aks_cluster/output.tf: -------------------------------------------------------------------------------- 1 | #Outputs 2 | output "client_key" { 3 | value = azurerm_kubernetes_cluster.k8cluster.kube_config.0.client_key 4 | } 5 | 6 | output "client_certificate" { 7 | value = azurerm_kubernetes_cluster.k8cluster.kube_config.0.client_certificate 8 | } 9 | 10 | output "cluster_ca_certificate" { 11 | value = azurerm_kubernetes_cluster.k8cluster.kube_config.0.cluster_ca_certificate 12 | } 13 | 14 | output "cluster_username" { 15 | value = azurerm_kubernetes_cluster.k8cluster.kube_config.0.username 16 | } 17 | 18 | output "cluster_password" { 19 | value = azurerm_kubernetes_cluster.k8cluster.kube_config.0.password 20 | } 21 | 22 | output "kube_config" { 23 | value = azurerm_kubernetes_cluster.k8cluster.kube_config_raw 24 | } 25 | 26 | output "host" { 27 | value = azurerm_kubernetes_cluster.k8cluster.kube_config.0.host 28 | } -------------------------------------------------------------------------------- /beginners/azure/aks_cluster/variables.tf: -------------------------------------------------------------------------------- 1 | #Variable 2 | variable "client_id" {} 3 | 4 | variable "client_secret" {} 5 | 6 | variable "subscription_id" {} 7 | 8 | variable "tenant_id" {} 9 | 10 | variable "location" {} 11 | 12 | variable "cluster_name" {} 13 | 14 | variable "dns_prifix" {} 15 | 16 | variable "resource_group_name" {} 17 | 18 | variable "log_analytics_workspace_name" {} 19 | 20 | variable "log_analytics_workspace_location" { 21 | default = "eastus" 22 | } 23 | variable "log_analytics_workspace_sku" { 24 | default = "PerNode" 25 | } 26 | 27 | -------------------------------------------------------------------------------- /beginners/azure/linuxVM/README.md: -------------------------------------------------------------------------------- 1 | # Create a Linux Virtual Machine in Azure with Terraform 2 | 3 | **This module creates a linux virtual machine (UBUNTU 16.04)** 4 | 5 | > Note 1: This deployment is not free. If you are not on a free trail, it will incur a very small fee. So, its always a good practice to cleanup everything when you are done with the demo. 6 | 7 | > Note 2: We are creating a public IP address and attaching it to the VM to login via SSH. This is not a best practice and not recommended at all in a real production environment. So, please destroy the infrastructure after the demo. 8 | 9 | ## Resources in this module 10 | 11 | - A Resource Group 12 | - A Virtual network with a Subnet 13 | - A Network Security Group 14 | - Subnet and NSG Association 15 | - A Public IP Address 16 | - A Network Interface 17 | - A Linux Virtual Machine 18 | 19 | > Notice that in this module, we are using a **Prefix** variable. We can use it to append to all resources for names. 20 | 21 | ## Prerequisites 22 | 23 | Click [Here](https://github.com/collabnix/terraform/blob/master/beginners/azure/README.md) to know the process of initial set up. 24 | 25 | ## Steps 26 | 27 | - *$ cd beginners/azure/linuxVM* 28 | 29 | > Make sure you are in this directory. This is the directory from where we run terraform commands. 30 | 31 | ## Changes you need to make before execution 32 | 33 | - In **azurerm_network_security_group** resource, paste in your local IP Address in *source_address_prefix*. This will restrict SSH access to your machine. Click [here](https://www.whatsmyip.org/) to findout your local ip address. 34 | 35 | ## After the deployment 36 | 37 | - Once the deployment is successful, you can login to the virtual machine. Login to the portal, go to the VM and click on Connect and select SSH. 38 | 39 | - Cleanup everything with **$ terraform destroy -auto-approve** 40 | -------------------------------------------------------------------------------- /beginners/azure/linuxVM/linuxvm.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 2 | # Create a Linux VM 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 4 | 5 | # 6 | # - Provider Block 7 | # 8 | 9 | provider "azurerm" { 10 | version = ">=2.6" 11 | client_id = var.client_id 12 | client_secret = var.client_secret 13 | subscription_id = var.subscription_id 14 | tenant_id = var.tenant_id 15 | 16 | features {} 17 | } 18 | 19 | # 20 | # - Create a Resource Group 21 | # 22 | 23 | resource "azurerm_resource_group" "rg" { 24 | name = "${var.prefix}-rg" 25 | location = var.location 26 | tags = var.tags 27 | } 28 | 29 | # 30 | # - Create a Virtual Network 31 | # 32 | 33 | resource "azurerm_virtual_network" "vnet" { 34 | name = "${var.prefix}-vnet" 35 | resource_group_name = azurerm_resource_group.rg.name 36 | location = azurerm_resource_group.rg.location 37 | address_space = [var.vnet_address_range] 38 | tags = var.tags 39 | } 40 | 41 | # 42 | # - Create a Subnet inside the virtual network 43 | # 44 | 45 | resource "azurerm_subnet" "web" { 46 | name = "${var.prefix}-web-subnet" 47 | resource_group_name = azurerm_resource_group.rg.name 48 | virtual_network_name = azurerm_virtual_network.vnet.name 49 | address_prefixes = [var.subnet_address_range] 50 | } 51 | 52 | # 53 | # - Create a Network Security Group 54 | # 55 | 56 | resource "azurerm_network_security_group" "nsg" { 57 | name = "${var.prefix}-web-nsg" 58 | resource_group_name = azurerm_resource_group.rg.name 59 | location = azurerm_resource_group.rg.location 60 | tags = var.tags 61 | 62 | security_rule { 63 | name = "Allow_SSH" 64 | priority = 1000 65 | direction = "Inbound" 66 | access = "Allow" 67 | protocol = "Tcp" 68 | source_port_range = "*" 69 | destination_port_range = 22 70 | source_address_prefix = "PASTE_YOUR_IP_ADDRESS_HERE" 71 | destination_address_prefix = "*" 72 | 73 | } 74 | } 75 | 76 | 77 | # 78 | # - Subnet-NSG Association 79 | # 80 | 81 | resource "azurerm_subnet_network_security_group_association" "subnet-nsg" { 82 | subnet_id = azurerm_subnet.web.id 83 | network_security_group_id = azurerm_network_security_group.nsg.id 84 | } 85 | 86 | 87 | # 88 | # - Public IP (To Login to Linux VM) 89 | # 90 | 91 | resource "azurerm_public_ip" "pip" { 92 | name = "${var.prefix}-linuxvm-public-ip" 93 | resource_group_name = azurerm_resource_group.rg.name 94 | location = azurerm_resource_group.rg.location 95 | allocation_method = var.allocation_method[0] 96 | tags = var.tags 97 | } 98 | 99 | # 100 | # - Create a Network Interface Card for Virtual Machine 101 | # 102 | 103 | resource "azurerm_network_interface" "nic" { 104 | name = "${var.prefix}-linuxvm-nic" 105 | resource_group_name = azurerm_resource_group.rg.name 106 | location = azurerm_resource_group.rg.location 107 | tags = var.tags 108 | ip_configuration { 109 | name = "${var.prefix}-nic-ipconfig" 110 | subnet_id = azurerm_subnet.web.id 111 | public_ip_address_id = azurerm_public_ip.pip.id 112 | private_ip_address_allocation = var.allocation_method[1] 113 | } 114 | } 115 | 116 | 117 | # 118 | # - Create a Linux Virtual Machine 119 | # 120 | 121 | resource "azurerm_linux_virtual_machine" "vm" { 122 | name = "${var.prefix}-linuxvm" 123 | resource_group_name = azurerm_resource_group.rg.name 124 | location = azurerm_resource_group.rg.location 125 | network_interface_ids = [azurerm_network_interface.nic.id] 126 | size = var.virtual_machine_size 127 | computer_name = var.computer_name 128 | admin_username = var.admin_username 129 | admin_password = var.admin_password 130 | disable_password_authentication = false 131 | 132 | os_disk { 133 | name = "${var.prefix}-linuxvm-os-disk" 134 | caching = var.os_disk_caching 135 | storage_account_type = var.os_disk_storage_account_type 136 | disk_size_gb = var.os_disk_size_gb 137 | } 138 | 139 | source_image_reference { 140 | publisher = var.publisher 141 | offer = var.offer 142 | sku = var.sku 143 | version = var.vm_image_version 144 | } 145 | 146 | tags = var.tags 147 | 148 | } 149 | 150 | -------------------------------------------------------------------------------- /beginners/azure/linuxVM/outputs.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 2 | # Linux VM - Outputs 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 4 | 5 | output "resource-group-name" { 6 | description = "Print the name of the resource group" 7 | value = azurerm_resource_group.rg.name 8 | } 9 | 10 | output "resource-group-location" { 11 | description = "Print the location of the resource group" 12 | value = azurerm_resource_group.rg.location 13 | } 14 | 15 | output "virtual-network-name" { 16 | description = "Print the name of the virtual network" 17 | value = azurerm_virtual_network.vnet.name 18 | } 19 | 20 | output "virtual-network-ip-range" { 21 | description = "Print the ip range of the virtual network" 22 | value = azurerm_virtual_network.vnet.address_space 23 | } 24 | 25 | output "subnet-name" { 26 | description = "Print the name of the subnet" 27 | value = azurerm_subnet.web.name 28 | } 29 | 30 | output "subnet-ip-range" { 31 | description = "Print the ip range of the subnet" 32 | value = [azurerm_subnet.web.address_prefixes] 33 | } 34 | 35 | output "linux_nic_name" { 36 | value = azurerm_network_interface.nic.name 37 | } 38 | 39 | output "public_ip_address" { 40 | value = azurerm_public_ip.pip.ip_address 41 | } 42 | 43 | output "linux_vm_login" { 44 | value = { 45 | "username" = azurerm_linux_virtual_machine.vm.admin_username 46 | "password" = azurerm_linux_virtual_machine.vm.admin_password 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /beginners/azure/linuxVM/variables.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 2 | # Linux VM - Variables 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 4 | 5 | # Service Principal Variables 6 | 7 | variable "client_id" { 8 | description = "Client ID (APP ID) of the application" 9 | type = string 10 | } 11 | 12 | variable "client_secret" { 13 | description = "Client Secret (Password) of the application" 14 | type = string 15 | } 16 | 17 | variable "subscription_id" { 18 | description = "Subscription ID" 19 | type = string 20 | } 21 | 22 | variable "tenant_id" { 23 | description = "Tenant ID" 24 | type = string 25 | } 26 | 27 | # Prefix and Tags 28 | 29 | variable "prefix" { 30 | description = "Prefix to append to all resource names" 31 | type = string 32 | default = "collabnix" 33 | } 34 | 35 | variable "tags" { 36 | description = "Resouce tags" 37 | type = map(string) 38 | default = { 39 | "project" = "Collabnix" 40 | "deployed_with" = "Terraform" 41 | } 42 | } 43 | 44 | # Resource Group 45 | 46 | variable "location" { 47 | description = "Location of the resource group" 48 | type = string 49 | default = "East US" 50 | } 51 | 52 | # Vnet and Subnet 53 | 54 | variable "vnet_address_range" { 55 | description = "IP Range of the virtual network" 56 | type = string 57 | default = "10.0.0.0/16" 58 | } 59 | 60 | variable "subnet_address_range" { 61 | description = "IP Range of the virtual network" 62 | type = string 63 | default = "10.0.1.0/24" 64 | } 65 | 66 | # Public IP and NIC Allocation Method 67 | 68 | variable "allocation_method" { 69 | description = "Allocation method for Public IP Address and NIC Private ip address" 70 | type = list(string) 71 | default = ["Static", "Dynamic"] 72 | } 73 | 74 | 75 | # VM 76 | 77 | variable "virtual_machine_size" { 78 | description = "Size of the VM" 79 | type = string 80 | default = "Standard_B1s" 81 | } 82 | 83 | variable "computer_name" { 84 | description = "Computer name" 85 | type = string 86 | default = "Linuxvm" 87 | } 88 | 89 | variable "admin_username" { 90 | description = "Username to login to the VM" 91 | type = string 92 | default = "linuxadmin" 93 | } 94 | 95 | variable "admin_password" { 96 | description = "Password to login to the VM" 97 | type = string 98 | default = "P@$$w0rD2020*" 99 | } 100 | 101 | variable "os_disk_caching" { 102 | default = "ReadWrite" 103 | } 104 | 105 | variable "os_disk_storage_account_type" { 106 | default = "StandardSSD_LRS" 107 | } 108 | 109 | variable "os_disk_size_gb" { 110 | default = 64 111 | } 112 | 113 | variable "publisher" { 114 | default = "Canonical" 115 | } 116 | 117 | variable "offer" { 118 | default = "UbuntuServer" 119 | } 120 | 121 | variable "sku" { 122 | default = "16.04-LTS" 123 | } 124 | 125 | variable "vm_image_version" { 126 | default = "latest" 127 | } 128 | -------------------------------------------------------------------------------- /beginners/azure/module_example/README.md: -------------------------------------------------------------------------------- 1 | # Create a Virtual Network in Azure with Terraform using Module 2 | 3 | **This module creates a virtual network with a subnet.** 4 | 5 | ## Prerequisites: 6 | 7 | Click [Here](https://github.com/collabnix/terraform/blob/master/beginners/azure/README.md) to know the process of initial set up. 8 | 9 | ## Steps: 10 | 11 | - *$ cd beginners/azure/module_example* 12 | 13 | > Make sure you are in this directory. This is the directory from where we run terraform commands. 14 | 15 | - In this directory, we have a folder called child_module. The child_module folder has all the resources to deploy a virtual network. So, instead of running terraform commands inside the child_module, we have modularized the virtual network deployment and calling it from the root module. This will enable us to reuse the configuration. 16 | 17 | - In the **module "vnet"** block, I have hardcoded all the values. You can also put variables in module block and assign the values in variables.tf 18 | 19 | - If you want to know and learn more about modules, click [here](https://www.terraform.io/docs/configuration/modules.html) 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /beginners/azure/module_example/child_module/README.md: -------------------------------------------------------------------------------- 1 | # Create a Virtual Network in Azure with Terraform 2 | 3 | **This module creates a virtual network with a subnet.** 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /beginners/azure/module_example/child_module/main.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Create a Virtual Network in Azure *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | # 6 | # - Create a Resource Group 7 | # 8 | 9 | resource "azurerm_resource_group" "rg" { 10 | name = var.resource_group_name 11 | location = var.location 12 | tags = { 13 | "project" = "Collabnix" 14 | "deployed_with" = "Terraform" 15 | } 16 | } 17 | 18 | # 19 | # - Create a Virtual Network 20 | # 21 | 22 | resource "azurerm_virtual_network" "vnet" { 23 | resource_group_name = azurerm_resource_group.rg.name 24 | name = var.virtual_network_name 25 | location = azurerm_resource_group.rg.location 26 | address_space = [var.vnet_address_range] 27 | tags = { 28 | "project" = "Collabnix" 29 | "deployed_with" = "Terraform" 30 | } 31 | } 32 | 33 | # 34 | # - Create a Subnet inside the virtual network 35 | # 36 | 37 | resource "azurerm_subnet" "sn" { 38 | name = var.subnet_name 39 | resource_group_name = azurerm_resource_group.rg.name 40 | virtual_network_name = azurerm_virtual_network.vnet.name 41 | address_prefixes = [var.subnet_address_range] 42 | } 43 | -------------------------------------------------------------------------------- /beginners/azure/module_example/child_module/outputs.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Create a Virtual Network in Azure - Outputs *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | output "resource-group-name" { 6 | description = "Print the name of the resource group" 7 | value = azurerm_resource_group.rg.name 8 | } 9 | 10 | output "resource-group-location" { 11 | description = "Print the location of the resource group" 12 | value = azurerm_resource_group.rg.location 13 | } 14 | 15 | output "virtual-network-name" { 16 | description = "Print the name of the virtual network" 17 | value = azurerm_virtual_network.vnet.name 18 | } 19 | 20 | output "virtual-network-ip-range" { 21 | description = "Print the ip range of the virtual network" 22 | value = azurerm_virtual_network.vnet.address_space 23 | } 24 | 25 | output "subnet-name" { 26 | description = "Print the name of the subnet" 27 | value = azurerm_subnet.sn.name 28 | } 29 | 30 | output "subnet-ip-range" { 31 | description = "Print the ip range of the subnet" 32 | value = [azurerm_subnet.sn.address_prefixes] 33 | } -------------------------------------------------------------------------------- /beginners/azure/module_example/child_module/variables.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Create a Virtual Network in Azure - Variables *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | # Resource Group Variables 6 | 7 | variable "resource_group_name" { 8 | description = "Name of the resource group" 9 | type = string 10 | } 11 | 12 | variable "location" { 13 | description = "Location of the resource group" 14 | type = string 15 | } 16 | 17 | # Vnet Variables 18 | 19 | variable "virtual_network_name" { 20 | description = "Name of the virtual network" 21 | type = string 22 | } 23 | 24 | variable "vnet_address_range" { 25 | description = "IP Range of the virtual network" 26 | type = string 27 | } 28 | 29 | # Subnet Variables 30 | 31 | variable "subnet_name" { 32 | description = "Name of the subnet" 33 | type = string 34 | } 35 | 36 | variable "subnet_address_range" { 37 | description = "IP Range of the virtual network" 38 | type = string 39 | } 40 | -------------------------------------------------------------------------------- /beginners/azure/module_example/main.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Using Modules in Terraform - Create a Vnet *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | # 6 | # - Provider Block 7 | # 8 | 9 | provider "azurerm" { 10 | client_id = var.client_id 11 | client_secret = var.client_secret 12 | subscription_id = var.subscription_id 13 | tenant_id = var.tenant_id 14 | 15 | features {} 16 | } 17 | 18 | # 19 | # - Deploy a Vnet in Azure 20 | # 21 | 22 | 23 | module "vnet" { 24 | source = "./child_module" 25 | resource_group_name = "Collabnix-RG" 26 | location = "East US" 27 | virtual_network_name = "Collabnix-Vnet" 28 | vnet_address_range = "10.0.0.0/16" 29 | subnet_name = "Webserver-Subnet" 30 | subnet_address_range = "10.0.1.0/24" 31 | 32 | } 33 | -------------------------------------------------------------------------------- /beginners/azure/module_example/outputs.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Root Module - Outputs *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | output "resource-group-name" { 6 | description = "Print the name of the resource group" 7 | value = module.vnet.resource-group-name 8 | } 9 | 10 | output "resource-group-location" { 11 | description = "Print the location of the resource group" 12 | value = module.vnet.resource-group-location 13 | } 14 | 15 | output "virtual-network-name" { 16 | description = "Print the name of the virtual network" 17 | value = module.vnet.virtual-network-name 18 | } 19 | 20 | output "virtual-network-ip-range" { 21 | description = "Print the ip range of the virtual network" 22 | value = module.vnet.virtual-network-ip-range 23 | } 24 | 25 | output "subnet-name" { 26 | description = "Print the name of the subnet" 27 | value = module.vnet.subnet-name 28 | } 29 | 30 | output "subnet-ip-range" { 31 | description = "Print the ip range of the subnet" 32 | value = module.vnet.subnet-ip-range 33 | } -------------------------------------------------------------------------------- /beginners/azure/module_example/variables.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Using Modules in Terraform - Create a Vnet *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | # Service Principal Variables 6 | 7 | variable "client_id" { 8 | description = "Client ID (APP ID) of the application" 9 | type = string 10 | } 11 | 12 | variable "client_secret" { 13 | description = "Client Secret (Password) of the application" 14 | type = string 15 | } 16 | 17 | variable "subscription_id" { 18 | description = "Subscription ID" 19 | type = string 20 | } 21 | 22 | variable "tenant_id" { 23 | description = "Tenant ID" 24 | type = string 25 | } 26 | 27 | -------------------------------------------------------------------------------- /beginners/azure/multiple_resources/README.md: -------------------------------------------------------------------------------- 1 | # Create multiple resources using for_each 2 | 3 | **In this module, we use for_each to deploy multiple resource groups in different locations, a Virtual network and multiple Subnets.** 4 | 5 | > You can also use *count* or *dynamic_block* to deploy multiple resources. 6 | 7 | ## Outputs 8 | 9 | 10 | 11 | - resource-group = { 12 | - "Dev-RG" = "southindia" 13 | - "QA-RG" = "westindia" 14 | - "Prod-RG" = "centralindia" 15 | } 16 | 17 | - vnet = { 18 | - "Vnet_Address" = ["10.0.0.0/16",] 19 | - "Vnet_Name" = "Dev-Vnet" 20 | } 21 | 22 | - subnet = { 23 | - "Web-Subnet" = ["10.0.1.0/24",] 24 | - "App-Subnet" = ["10.0.2.0/24",] 25 | - "DB-Subnet" = ["10.0.3.0/24",] 26 | 27 | } 28 | 29 | -------------------------------------------------------------------------------- /beginners/azure/multiple_resources/main.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Create multiple resources using for_each *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | # 6 | # - Provider Block 7 | # 8 | 9 | provider "azurerm" { 10 | version = ">=2.6" 11 | client_id = var.client_id 12 | client_secret = var.client_secret 13 | subscription_id = var.subscription_id 14 | tenant_id = var.tenant_id 15 | 16 | features {} 17 | } 18 | 19 | # 20 | # - Create multiple Resource Groups 21 | # 22 | 23 | resource "azurerm_resource_group" "rg" { 24 | for_each = var.resource_group 25 | name = each.key 26 | location = each.value 27 | tags = var.tags 28 | } 29 | 30 | # 31 | # - Create a Virtual Network 32 | # 33 | 34 | 35 | resource "azurerm_virtual_network" "vnet" { 36 | resource_group_name = azurerm_resource_group.rg["Dev-RG"].name 37 | name = var.virtual_network["name"] 38 | location = azurerm_resource_group.rg["Dev-RG"].location 39 | address_space = [var.virtual_network["address_range"]] 40 | tags = var.tags 41 | } 42 | 43 | 44 | # 45 | # - Create multiple Subnets inside the virtual network 46 | # 47 | 48 | resource "azurerm_subnet" "sn" { 49 | for_each = var.subnet 50 | name = each.key 51 | resource_group_name = azurerm_resource_group.rg["Dev-RG"].name 52 | virtual_network_name = azurerm_virtual_network.vnet.name 53 | address_prefixes = [each.value] 54 | } -------------------------------------------------------------------------------- /beginners/azure/multiple_resources/outputs.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Create multiple resources using for_each *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | output "resource-group" { 6 | description = "Map resource group name with location" 7 | value = { for i in azurerm_resource_group.rg: i.name => i.location } 8 | } 9 | 10 | output "vnet" { 11 | description = "Print Vnet name and Address Space" 12 | value = { 13 | "Vnet_Name" = azurerm_virtual_network.vnet.name 14 | "Vnet_Address" = azurerm_virtual_network.vnet.address_space 15 | } 16 | } 17 | 18 | output "subnet" { 19 | description = "Map subnet name with address_prefixes" 20 | value = { for s in azurerm_subnet.sn: s.name => s.address_prefixes } 21 | } 22 | -------------------------------------------------------------------------------- /beginners/azure/multiple_resources/variables.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Create multiple resources using for_each *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | 6 | # Service Principal Variables 7 | 8 | variable "client_id" { 9 | description = "Client ID (APP ID) of the application" 10 | type = string 11 | } 12 | 13 | variable "client_secret" { 14 | description = "Client Secret (Password) of the application" 15 | type = string 16 | } 17 | 18 | variable "subscription_id" { 19 | description = "Subscription ID" 20 | type = string 21 | } 22 | 23 | variable "tenant_id" { 24 | description = "Tenant ID" 25 | type = string 26 | } 27 | 28 | variable "tags" { 29 | description = "Tags" 30 | type = map(string) 31 | default = { 32 | "Project" = "Collabnix" 33 | "Deployed_with" = "Terraform" 34 | "Track" = "Beginner" 35 | } 36 | } 37 | 38 | # 39 | # - Resource Group Variables 40 | # 41 | 42 | variable "resource_group" { 43 | description = "Create multiple resource groups" 44 | type = map(string) 45 | default = { 46 | "Dev-RG" = "South India" 47 | "QA-RG" = "West India" 48 | "Prod-RG" = "Central India" 49 | } 50 | } 51 | 52 | # 53 | # - Virtual Network Variables 54 | # 55 | 56 | variable "virtual_network" { 57 | description = "Virtual Network variables" 58 | type = map(string) 59 | default = { 60 | "name" = "Dev-Vnet" 61 | "address_range" = "10.0.0.0/16" 62 | } 63 | } 64 | 65 | # 66 | # - Subnet Variables 67 | # 68 | 69 | variable "subnet" { 70 | description = "Create multiple subnets" 71 | type = map(string) 72 | default = { 73 | "Web-Subnet" = "10.0.1.0/24" 74 | "App-Subnet" = "10.0.2.0/24" 75 | "DB-Subnet" = "10.0.3.0/24" 76 | } 77 | } -------------------------------------------------------------------------------- /beginners/azure/storageAccount/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Static Website on Azure 4 | 5 | 6 |

Oopsie. Something is wrong

7 |
8 | 9 | -------------------------------------------------------------------------------- /beginners/azure/storageAccount/README.md: -------------------------------------------------------------------------------- 1 | # Create a Static Website on Azure Storage account with Terraform 2 | 3 | **This module creates a Storage account in Azure and hosts a static website** 4 | 5 | > Note 1: This deployment is not free. If you are not on a free trail, it will incur a very small fee. So, its always a good practice to cleanup everything when you are done with the demo. 6 | 7 | ## Resources in this module 8 | 9 | - A Resource Group 10 | - A Storage Account 11 | 12 | ## Prerequisites 13 | 14 | Click [Here](https://github.com/collabnix/terraform/blob/master/beginners/azure/README.md) to know the process of initial set up. 15 | 16 | ## Steps 17 | 18 | - *$ cd beginners/azure/storageAccount* 19 | 20 | > Make sure you are in this directory. This is the directory from where we run terraform commands. 21 | 22 | - After the storage account is created, copy the url from the output, paste it in a browser. You should see the below page 23 | 24 | 25 | 26 | ![Success](https://github.com/collabnix/terraform/blob/master/images/Azure_staticwebsite_Success.png) 27 | 28 | - If you want to see the error page, append /error to the url. 29 | 30 | 31 | 32 | ![Error](https://github.com/collabnix/terraform/blob/master/images/Azure_staticwebsite_Error.png) 33 | 34 | 35 | ## After the deployment 36 | 37 | - Cleanup everything with **$ terraform destroy -auto-approve** 38 | -------------------------------------------------------------------------------- /beginners/azure/storageAccount/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Static Website on Azure 4 | 5 | 6 |

This website is running on Azure Storage

7 |
8 | 9 | -------------------------------------------------------------------------------- /beginners/azure/storageAccount/outputs.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Storage account with Network Rules - Outputs *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | output "storage_account_name" { 6 | description = "Name of the storage account" 7 | value = azurerm_storage_account.sa.name 8 | } 9 | 10 | output "website-url" { 11 | description = "URL of the static website" 12 | value = azurerm_storage_account.sa.primary_web_endpoint 13 | } -------------------------------------------------------------------------------- /beginners/azure/storageAccount/storageaccount.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Host a Static Website on Azure Storage *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | # 6 | # - Provider Block 7 | # 8 | 9 | provider "azurerm" { 10 | version = ">=2.6" 11 | client_id = var.client_id 12 | client_secret = var.client_secret 13 | subscription_id = var.subscription_id 14 | tenant_id = var.tenant_id 15 | 16 | features {} 17 | } 18 | 19 | # 20 | # - Create a Resource Group 21 | # 22 | 23 | resource "azurerm_resource_group" "rg" { 24 | name = "${var.prefix}-rg" 25 | location = var.location 26 | tags = var.tags 27 | } 28 | 29 | # 30 | # - Create a Random integer to append to Storage account name 31 | # 32 | 33 | resource "random_integer" "sa_name" { 34 | min = 1111 35 | max = 9999 36 | # Result will be like this - 1325 37 | } 38 | 39 | # 40 | # - Create a Storage account with Network Rules 41 | # 42 | 43 | resource "azurerm_storage_account" "sa" { 44 | name = "${var.saVars["name"]}${random_integer.sa_name.result}" 45 | resource_group_name = azurerm_resource_group.rg.name 46 | location = azurerm_resource_group.rg.location 47 | account_kind = var.saVars["account_kind"] 48 | account_tier = var.saVars["account_tier"] 49 | access_tier = var.saVars["access_tier"] 50 | account_replication_type = var.saVars["account_replication_type"] 51 | 52 | static_website { 53 | index_document = "index.html" 54 | error_404_document = "404.html" 55 | } 56 | 57 | tags = var.tags 58 | } 59 | 60 | 61 | resource "azurerm_storage_blob" "website" { 62 | for_each = var.blobs 63 | name = each.key 64 | storage_account_name = azurerm_storage_account.sa.name 65 | storage_container_name = "$web" 66 | type = "Block" 67 | content_type = "text/html" 68 | source = each.value 69 | } -------------------------------------------------------------------------------- /beginners/azure/storageAccount/variables.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Storage account with Network Rules - Variables *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | # Service Principal Variables 6 | 7 | variable "client_id" { 8 | description = "Client ID (APP ID) of the application" 9 | type = string 10 | } 11 | 12 | variable "client_secret" { 13 | description = "Client Secret (Password) of the application" 14 | type = string 15 | } 16 | 17 | variable "subscription_id" { 18 | description = "Subscription ID" 19 | type = string 20 | } 21 | 22 | variable "tenant_id" { 23 | description = "Tenant ID" 24 | type = string 25 | } 26 | 27 | # Prefix and Tags 28 | 29 | variable "prefix" { 30 | description = "Prefix to append to all resource names" 31 | type = string 32 | default = "collabnix" 33 | } 34 | 35 | variable "tags" { 36 | description = "Resouce tags" 37 | type = map(string) 38 | default = { 39 | "project" = "Collabnix" 40 | "deployed_with" = "Terraform" 41 | } 42 | } 43 | 44 | # Resource Group 45 | 46 | variable "location" { 47 | description = "Location of the resource group" 48 | type = string 49 | default = "East US" 50 | } 51 | 52 | # Vnet and Subnet 53 | 54 | variable "vnet_address_range" { 55 | description = "IP Range of the virtual network" 56 | type = string 57 | default = "10.0.0.0/16" 58 | } 59 | 60 | variable "subnet_address_range" { 61 | description = "IP Range of the virtual network" 62 | type = string 63 | default = "10.0.1.0/24" 64 | } 65 | 66 | # Storage account 67 | 68 | variable "saVars" { 69 | description = "Variables for Storage account" 70 | type = map(string) 71 | default = { 72 | "name" = "collabnixsa" 73 | "account_kind" = "StorageV2" 74 | "account_tier" = "Standard" 75 | "access_tier" = "Hot" 76 | "account_replication_type" = "LRS" 77 | "default_action" = "Deny" 78 | "ip_rules" = "124.123.72.15" 79 | "bypass" = "None" 80 | } 81 | } 82 | 83 | variable "blobs" { 84 | description = "Files to upload to the container" 85 | type = map(string) 86 | default = { 87 | "index.html" = "./index.html" 88 | "404.html" = "./404.html" 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /beginners/azure/virtualnetwork/README.md: -------------------------------------------------------------------------------- 1 | # Create a Virtual Network in Azure with Terraform 2 | 3 | **This module creates a virtual network with a subnet.** 4 | 5 | ## Prerequisites: 6 | 7 | Click [Here](https://github.com/collabnix/terraform/blob/master/beginners/azure/README.md) to know the process of initial set up. 8 | 9 | ## Steps: 10 | 11 | - *$ cd beginners/azure/virtualnetwork* 12 | 13 | > Make sure you are in this directory. This is the directory from where we run terraform commands. 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /beginners/azure/virtualnetwork/main.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Create a Virtual Network in Azure *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | # 6 | # - Provider Block 7 | # 8 | 9 | provider "azurerm" { 10 | version = ">=2.6" 11 | client_id = var.client_id 12 | client_secret = var.client_secret 13 | subscription_id = var.subscription_id 14 | tenant_id = var.tenant_id 15 | 16 | features {} 17 | } 18 | 19 | # 20 | # - Create a Resource Group 21 | # 22 | 23 | resource "azurerm_resource_group" "rg" { 24 | name = var.resource_group_name 25 | location = var.location 26 | tags = { 27 | "project" = "Collabnix" 28 | "deployed_with" = "Terraform" 29 | } 30 | } 31 | 32 | # 33 | # - Create a Virtual Network 34 | # 35 | 36 | resource "azurerm_virtual_network" "vnet" { 37 | resource_group_name = azurerm_resource_group.rg.name 38 | name = var.virtual_network_name 39 | location = azurerm_resource_group.rg.location 40 | address_space = [var.vnet_address_range] 41 | tags = { 42 | "project" = "Collabnix" 43 | "deployed_with" = "Terraform" 44 | } 45 | } 46 | 47 | # 48 | # - Create a Subnet inside the virtual network 49 | # 50 | 51 | resource "azurerm_subnet" "sn" { 52 | name = var.subnet_name 53 | resource_group_name = azurerm_resource_group.rg.name 54 | virtual_network_name = azurerm_virtual_network.vnet.name 55 | address_prefixes = [var.subnet_address_range] 56 | } 57 | -------------------------------------------------------------------------------- /beginners/azure/virtualnetwork/outputs.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Create a Virtual Network in Azure - Outputs *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | output "resource-group-name" { 6 | description = "Print the name of the resource group" 7 | value = azurerm_resource_group.rg.name 8 | } 9 | 10 | output "resource-group-location" { 11 | description = "Print the location of the resource group" 12 | value = azurerm_resource_group.rg.location 13 | } 14 | 15 | output "virtual-network-name" { 16 | description = "Print the name of the virtual network" 17 | value = azurerm_virtual_network.vnet.name 18 | } 19 | 20 | output "virtual-network-ip-range" { 21 | description = "Print the ip range of the virtual network" 22 | value = azurerm_virtual_network.vnet.address_space 23 | } 24 | 25 | output "subnet-name" { 26 | description = "Print the name of the subnet" 27 | value = azurerm_subnet.sn.name 28 | } 29 | 30 | output "subnet-ip-range" { 31 | description = "Print the ip range of the subnet" 32 | value = [azurerm_subnet.sn.address_prefixes] 33 | } -------------------------------------------------------------------------------- /beginners/azure/virtualnetwork/variables.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Create a Virtual Network in Azure - Variables *# 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | # Service Principal Variables 6 | 7 | variable "client_id" { 8 | description = "Client ID (APP ID) of the application" 9 | type = string 10 | } 11 | 12 | variable "client_secret" { 13 | description = "Client Secret (Password) of the application" 14 | type = string 15 | } 16 | 17 | variable "subscription_id" { 18 | description = "Subscription ID" 19 | type = string 20 | } 21 | 22 | variable "tenant_id" { 23 | description = "Tenant ID" 24 | type = string 25 | } 26 | 27 | # Resource Group Variables 28 | 29 | variable "resource_group_name" { 30 | description = "Name of the resource group" 31 | type = string 32 | default = "Collabnix-RG" 33 | } 34 | 35 | variable "location" { 36 | description = "Location of the resource group" 37 | type = string 38 | default = "East US" 39 | } 40 | 41 | variable "virtual_network_name" { 42 | description = "Name of the virtual network" 43 | type = string 44 | default = "Collabnix-Vnet" 45 | } 46 | 47 | variable "vnet_address_range" { 48 | description = "IP Range of the virtual network" 49 | type = string 50 | default = "10.0.0.0/16" 51 | } 52 | 53 | variable "subnet_name" { 54 | description = "Name of the subnet" 55 | type = string 56 | default = "Webserver-Subnet" 57 | } 58 | 59 | variable "subnet_address_range" { 60 | description = "IP Range of the virtual network" 61 | type = string 62 | default = "10.0.1.0/24" 63 | } -------------------------------------------------------------------------------- /beginners/azure/windowsVM/README.md: -------------------------------------------------------------------------------- 1 | # Create a Windows 10 Virtual Machine in Azure with Terraform 2 | 3 | **This module creates a Windows virtual machine (Windows 10 Pro)** 4 | 5 | > Note 1: This deployment is not free. If you are not on a free trail, it will incur a very small fee. So, its always a good practice to cleanup everything when you are done with the demo. 6 | 7 | > Note 2: We are creating a public IP address and attaching it to the VM to login via RDP. This is not a best practice and not recommended at all in a real production environment. So, please destroy the infrastructure after the demo. 8 | 9 | ## Resources in this module 10 | 11 | - A Resource Group 12 | - A Virtual network with a Subnet 13 | - A Network Security Group 14 | - Subnet and NSG Association 15 | - A Public IP Address 16 | - A Network Interface 17 | - A Windows Virtual Machine 18 | 19 | > Notice that in this module, we are using a **Prefix** variable. We can use it to append to all resources for names. 20 | 21 | ## Prerequisites 22 | 23 | Click [Here](https://github.com/collabnix/terraform/blob/master/beginners/azure/README.md) to know the process of initial set up. 24 | 25 | ## Steps 26 | 27 | - *$ cd beginners/azure/windowsVM* 28 | 29 | > Make sure you are in this directory. This is the directory from where we run terraform commands. 30 | 31 | ## Changes you need to make before execution 32 | 33 | - In **azurerm_network_security_group** resource, paste in your local IP Address in *source_address_prefix*. This will restrict SSH access to your machine. Click [here](https://www.whatsmyip.org/) to findout your local ip address. 34 | 35 | ## After the deployment 36 | 37 | - Once the deployment is successful, you can login to the virtual machine. Login to the portal, go to the VM and click on Connect and select RDP. 38 | - Download the RDP file. If you are on Windows, you can connect to the VM using Remote Desktop. If you are on Mac, download and install "Microsoft Remote Desktop" application from the appstore. 39 | 40 | - Cleanup everything with **$ terraform destroy -auto-approve** 41 | -------------------------------------------------------------------------------- /beginners/azure/windowsVM/outputs.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 2 | # Windows VM - Outputs 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 4 | 5 | output "resource-names" { 6 | description = "Print the names of the resources" 7 | value = { 8 | "Resource-Group-Name" = azurerm_resource_group.rg.name 9 | "Vnet-Name" = azurerm_virtual_network.vnet.name 10 | "Subnet-Name" = azurerm_subnet.web.name 11 | "NSG-Name" = azurerm_network_security_group.nsg.name 12 | "NIC-Name" = azurerm_network_interface.nic.name 13 | } 14 | } 15 | 16 | 17 | output "public_ip_address" { 18 | value = azurerm_public_ip.pip.ip_address 19 | } 20 | 21 | output "win_vm_login" { 22 | description = "Credentials to login to the VM" 23 | value = { 24 | "VM-Name" = azurerm_windows_virtual_machine.vm.name 25 | "Username" = azurerm_windows_virtual_machine.vm.admin_username 26 | "Password" = azurerm_windows_virtual_machine.vm.admin_password 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /beginners/azure/windowsVM/variables.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 2 | # Windows 10 VM - Variables 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 4 | 5 | # Service Principal Variables 6 | 7 | variable "client_id" { 8 | description = "Client ID (APP ID) of the application" 9 | type = string 10 | } 11 | 12 | variable "client_secret" { 13 | description = "Client Secret (Password) of the application" 14 | type = string 15 | } 16 | 17 | variable "subscription_id" { 18 | description = "Subscription ID" 19 | type = string 20 | } 21 | 22 | variable "tenant_id" { 23 | description = "Tenant I D" 24 | type = string 25 | } 26 | 27 | # Prefix and Tags 28 | 29 | variable "prefix" { 30 | description = "Prefix to append to all resource names" 31 | type = string 32 | default = "collabnix" 33 | } 34 | 35 | variable "tags" { 36 | description = "Resouce tags" 37 | type = map(string) 38 | default = { 39 | "project" = "Collabnix" 40 | "deployed_with" = "Terraform" 41 | } 42 | } 43 | 44 | # Resource Group 45 | 46 | variable "location" { 47 | description = "Location of the resource group" 48 | type = string 49 | default = "East US" 50 | } 51 | 52 | # Vnet and Subnet 53 | 54 | variable "vnet_address_range" { 55 | description = "IP Range of the virtual network" 56 | type = string 57 | default = "10.0.0.0/16" 58 | } 59 | 60 | variable "subnet_address_range" { 61 | description = "IP Range of the virtual network" 62 | type = string 63 | default = "10.0.1.0/24" 64 | } 65 | 66 | # Public IP and NIC Allocation Method 67 | 68 | variable "allocation_method" { 69 | description = "Allocation method for Public IP Address and NIC Private ip address" 70 | type = list(string) 71 | default = ["Static", "Dynamic"] 72 | } 73 | 74 | 75 | # VM 76 | 77 | variable "virtual_machine_size" { 78 | description = "Size of the VM" 79 | type = string 80 | default = "Standard_B1s" 81 | } 82 | 83 | variable "computer_name" { 84 | description = "Computer name" 85 | type = string 86 | default = "Win10vm" 87 | } 88 | 89 | variable "admin_username" { 90 | description = "Username to login to the VM" 91 | type = string 92 | default = "winadmin" 93 | } 94 | 95 | variable "admin_password" { 96 | description = "Password to login to the VM" 97 | type = string 98 | default = "P@$$w0rD2020*" 99 | } 100 | 101 | variable "os_disk_caching" { 102 | default = "ReadWrite" 103 | } 104 | 105 | variable "os_disk_storage_account_type" { 106 | default = "StandardSSD_LRS" 107 | } 108 | 109 | variable "os_disk_size_gb" { 110 | default = 128 111 | } 112 | 113 | variable "publisher" { 114 | default = "MicrosoftWindowsDesktop" 115 | } 116 | 117 | variable "offer" { 118 | default = "Windows-10" 119 | } 120 | 121 | variable "sku" { 122 | default = "rs5-pro" 123 | } 124 | 125 | variable "vm_image_version" { 126 | default = "latest" 127 | } 128 | -------------------------------------------------------------------------------- /beginners/azure/windowsVM/windowsvm.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 2 | # Create a Windows VM 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 4 | 5 | # 6 | # - Provider Block 7 | # 8 | 9 | provider "azurerm" { 10 | version = ">=2.6" 11 | client_id = var.client_id 12 | client_secret = var.client_secret 13 | subscription_id = var.subscription_id 14 | tenant_id = var.tenant_id 15 | 16 | features {} 17 | } 18 | 19 | # 20 | # - Create a Resource Group 21 | # 22 | 23 | resource "azurerm_resource_group" "rg" { 24 | name = "${var.prefix}-rg" 25 | location = var.location 26 | tags = var.tags 27 | } 28 | 29 | # 30 | # - Create a Virtual Network 31 | # 32 | 33 | resource "azurerm_virtual_network" "vnet" { 34 | name = "${var.prefix}-vnet" 35 | resource_group_name = azurerm_resource_group.rg.name 36 | location = azurerm_resource_group.rg.location 37 | address_space = [var.vnet_address_range] 38 | tags = var.tags 39 | } 40 | 41 | # 42 | # - Create a Subnet inside the virtual network 43 | # 44 | 45 | resource "azurerm_subnet" "web" { 46 | name = "${var.prefix}-web-subnet" 47 | resource_group_name = azurerm_resource_group.rg.name 48 | virtual_network_name = azurerm_virtual_network.vnet.name 49 | address_prefixes = [var.subnet_address_range] 50 | } 51 | 52 | # 53 | # - Create a Network Security Group 54 | # 55 | 56 | resource "azurerm_network_security_group" "nsg" { 57 | name = "${var.prefix}-web-nsg" 58 | resource_group_name = azurerm_resource_group.rg.name 59 | location = azurerm_resource_group.rg.location 60 | tags = var.tags 61 | 62 | security_rule { 63 | name = "Allow_RDP" 64 | priority = 1000 65 | direction = "Inbound" 66 | access = "Allow" 67 | protocol = "Tcp" 68 | source_port_range = "*" 69 | destination_port_range = 3389 70 | source_address_prefix = "PASTE_YOUR_IP_ADDRESS_HERE" 71 | destination_address_prefix = "*" 72 | 73 | } 74 | } 75 | 76 | 77 | # 78 | # - Subnet-NSG Association 79 | # 80 | 81 | resource "azurerm_subnet_network_security_group_association" "subnet-nsg" { 82 | subnet_id = azurerm_subnet.web.id 83 | network_security_group_id = azurerm_network_security_group.nsg.id 84 | } 85 | 86 | 87 | # 88 | # - Public IP (To Login to Linux VM) 89 | # 90 | 91 | resource "azurerm_public_ip" "pip" { 92 | name = "${var.prefix}-winvm-public-ip" 93 | resource_group_name = azurerm_resource_group.rg.name 94 | location = azurerm_resource_group.rg.location 95 | allocation_method = var.allocation_method[0] 96 | tags = var.tags 97 | } 98 | 99 | # 100 | # - Create a Network Interface Card for Virtual Machine 101 | # 102 | 103 | resource "azurerm_network_interface" "nic" { 104 | name = "${var.prefix}-winvm-nic" 105 | resource_group_name = azurerm_resource_group.rg.name 106 | location = azurerm_resource_group.rg.location 107 | tags = var.tags 108 | ip_configuration { 109 | name = "${var.prefix}-nic-ipconfig" 110 | subnet_id = azurerm_subnet.web.id 111 | public_ip_address_id = azurerm_public_ip.pip.id 112 | private_ip_address_allocation = var.allocation_method[1] 113 | } 114 | } 115 | 116 | 117 | # 118 | # - Create a Windows 10 Virtual Machine 119 | # 120 | 121 | resource "azurerm_windows_virtual_machine" "vm" { 122 | name = "${var.prefix}-winvm" 123 | resource_group_name = azurerm_resource_group.rg.name 124 | location = azurerm_resource_group.rg.location 125 | network_interface_ids = [azurerm_network_interface.nic.id] 126 | size = var.virtual_machine_size 127 | computer_name = var.computer_name 128 | admin_username = var.admin_username 129 | admin_password = var.admin_password 130 | 131 | os_disk { 132 | name = "${var.prefix}-winvm-os-disk" 133 | caching = var.os_disk_caching 134 | storage_account_type = var.os_disk_storage_account_type 135 | disk_size_gb = var.os_disk_size_gb 136 | } 137 | 138 | source_image_reference { 139 | publisher = var.publisher 140 | offer = var.offer 141 | sku = var.sku 142 | version = var.vm_image_version 143 | } 144 | 145 | tags = var.tags 146 | 147 | } 148 | 149 | -------------------------------------------------------------------------------- /beginners/gcp/README.md: -------------------------------------------------------------------------------- 1 | # How to setup Terraform for Google Cloud Engine 2 | 3 | 4 | ### Pre-requiste 5 | 6 | In order to avoid explicitly using the GCP service key, we are going to use GOOGLE_APPLICATION_CREDENTIAL environment variable that points to our GCP service key. 7 | 8 | ## Installing Terraform ~> 0.12.26 9 | 10 | If you have a service key at your disposal
11 | 12 | ``` 13 | export GOOGLE_APPLICATION_CREDENTIAL = {path to your service key file} 14 | ``` 15 | 16 | If you have not created a service account and a service key then follow below steps 17 | 18 | ## Install gcloud cli 19 | 20 | The gcloud cli is a part of [Google Cloud SDK](https://cloud.google.com/sdk/docs). We must download and install the SDK on your system and initialize it before you can use the gcloud command-line tool. 21 | 22 | Note: You can follow the install script given in the Google Cloud SDK documentation. 23 | 24 | ## Google Cloud SDK Quickstart script for CentOS 25 | 26 | ``` 27 | sudo tee -a /etc/yum.repos.d/google-cloud-sdk.repo << EOM 28 | [google-cloud-sdk] 29 | name=Google Cloud SDK 30 | baseurl=https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64 31 | enabled=1 32 | gpgcheck=1 33 | repo_gpgcheck=1 34 | gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg 35 | https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg 36 | EOM 37 | ``` 38 | 39 | ## Installing Google cloud SDK 40 | 41 | ``` 42 | yum install google-cloud-sdk 43 | ``` 44 | 45 | Once the SDK is installed, run gcloud init to initialize the SDK, 46 | 47 | ``` 48 | gcloud init 49 | ``` 50 | 51 | ## Run the following scripts 52 | 53 | ````bash 54 | export PROJECT_ID={Name of your GCP Project} 55 | 56 | export GOOGLE_APPLICATION_CREDENTIALS=~/.config/gcloud/${PROJECT_ID}-terraform-admin.json 57 | 58 | gcloud iam service-accounts create terraform --display-name "Terraform admin account" 59 | 60 | gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:terraform@${PROJECT_ID}.iam.gserviceaccount.com --role roles/owner 61 | 62 | gcloud services enable compute.googleapis.com 63 | 64 | gcloud services enable iam.googleapis.com 65 | 66 | gcloud iam service-accounts keys create ${GOOGLE_APPLICATION_CREDENTIALS} --iam-account terraform@${PROJECT_ID}.iam.gserviceaccount.com``` 67 | ```` 68 | 69 | **Note** - you would need to export the GOOGLE_APPLICATION_CREDENTIALS every time you work with terraform when interacting with your configurations. 70 | -------------------------------------------------------------------------------- /beginners/gcp/TerraformVsGoogleDeploymentManager/README.md: -------------------------------------------------------------------------------- 1 | #### Terraform vs Google Deployment Manager 2 | 3 | `Terraform` is a widely-used Public Cloud tool whereas `Google Deployment Manager` is only a GCP-native IaC tool. 4 | 5 | Terraform: 6 | 1. Multi-Cloud Deployment: You can use terraform in all three major public cloud providers as AWS, Google Cloud and Azure. 7 | 2. Terraform uses HCL: This is HashiCorp's Configuration Language for creating IaC solutions for Cloud. 8 | 3. All Major Cloud Services are supported: All major cloud services are with Terraform and new major services are supported as soon as they are launched. 9 | 10 | Google Deployment Manager: 11 | 1. Used on GCP Only: Deployment Manager is used for GCP services only, similar to ARM templates in Azure and CloudFormation in AWS. 12 | 2. You can Deploy Marketplace Solutions: User can use images from Google Cloud Marketplace to deploy with Deployment Manager. 13 | 3. You can use Python and Jinja2 Templates: Deployment Manager allows the use of Python and Jinja templates for configuration. This can allow the reuse of common deployments. 14 | 15 | ![Terraform vs Google Deployment Manager](/images/TerraformVsDeployMgr.jpg) 16 | -------------------------------------------------------------------------------- /beginners/gcp/virtual-machine/README.md: -------------------------------------------------------------------------------- 1 | ## Create a Google compute instance in GCP 2 | 3 | In this particular track, we are going to build a google compute instance using terrform. 4 | We will be binding an instance with a static compute address and we'll also see how we can 5 | attach service account/ scope on a virtual machine. We will also install a nginx server on our instance and we'll also allow traffic at Port 80 using http-server tags. 6 | 7 | 8 | Add the necessary values of the variables in terraform.tfvars file 9 | 10 | ``` 11 | gcp_project_id="" 12 | gcp_project_location="" 13 | gcp_compute_zone="" 14 | machine_type="" 15 | ``` 16 | 17 | ### Terraform Init 18 | 19 | This command will all the providers for you that are required to create your resource in GCP 20 | 21 | ```bash 22 | cd virtual-machine 23 | terraform init 24 | ``` 25 | 26 | The CDN which servers the providers is quite slow that's why it can take some time for the providers to get downloaded 27 | 28 | ### Terraform plan 29 | 30 | This command will layout a plan for you and show you what all resources can be created 31 | 32 | ```bash 33 | cd virtual-machine 34 | terraform plan 35 | ``` 36 | 37 | ### Terraform apply 38 | 39 | This command will create all the mentioned resources for yor 40 | 41 | ```bash 42 | cd virtual-machine 43 | terraform apply 44 | ``` 45 | 46 | You'll be prompted a confirmation - Press yes. 47 | 48 | Once the resources have been created you should see 49 | 50 | ``` 51 | Apply complete! Resources: 0 added, 1 changed, 0 destroyed. 52 | 53 | Outputs: 54 | 55 | disk_name = disk-2a7c7a928746e7a6 56 | instance_name = vm-2a7c7a928746e7a6 57 | public_address = 34.87.216.228 58 | ``` 59 | 60 | Now if you will head over to the public address you should see nginx welcome page. 61 | -------------------------------------------------------------------------------- /beginners/gcp/virtual-machine/compute-address.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_address" "static" { 2 | name = "external-ip-${random_id.top_level_resource_suffix.hex}" 3 | } 4 | -------------------------------------------------------------------------------- /beginners/gcp/virtual-machine/compute-disk.tf: -------------------------------------------------------------------------------- 1 | # This disk will get attached to our VM. 2 | resource "google_compute_disk" "default" { 3 | name = "disk-${random_id.top_level_resource_suffix.hex}" 4 | type = "pd-ssd" 5 | size = 20 6 | zone = var.gcp_compute_zone 7 | image = data.google_compute_image.ubuntu_image.self_link 8 | } 9 | 10 | # This data source will get us the image name for Ubuntu. 11 | data "google_compute_image" "ubuntu_image" { 12 | family = "ubuntu-1604-lts" 13 | project = "ubuntu-os-cloud" 14 | } 15 | -------------------------------------------------------------------------------- /beginners/gcp/virtual-machine/compute-instance.tf: -------------------------------------------------------------------------------- 1 | # This resource will allow all the resources to have a particular prefix which will a user to 2 | # identify all the resources created by him. 3 | resource "random_id" "top_level_resource_suffix" { 4 | byte_length = 8 5 | } 6 | 7 | resource "google_compute_instance" "nginx" { 8 | name = "vm-${random_id.top_level_resource_suffix.hex}" 9 | machine_type = var.machine_type 10 | zone = var.gcp_compute_zone 11 | 12 | allow_stopping_for_update = true 13 | 14 | boot_disk { 15 | source = google_compute_disk.default.self_link 16 | } 17 | 18 | # A startup script that will run on our os and setup a nginx server for us 19 | metadata_startup_script = "sudo apt-get update; sudo apt-get install nginx-light -y" 20 | 21 | # Allows traffic @ PORT 80. It is recommended to use custom vpc and subnets with firewalls rules 22 | tags = ["http-server"] 23 | 24 | # Block where you can configure your vpc and subnets 25 | network_interface { 26 | network = "default" 27 | access_config { 28 | nat_ip = google_compute_address.static.address 29 | } 30 | } 31 | 32 | # Adding a service account 33 | service_account { 34 | scopes = ["https://www.googleapis.com/auth/monitoring"] 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /beginners/gcp/virtual-machine/outputs.tf: -------------------------------------------------------------------------------- 1 | output "instance_name" { 2 | value = google_compute_instance.nginx.name 3 | } 4 | 5 | output "disk_name" { 6 | value = google_compute_disk.default.name 7 | } 8 | 9 | output "public_address" { 10 | value = google_compute_address.static.address 11 | } 12 | -------------------------------------------------------------------------------- /beginners/gcp/virtual-machine/providers.tf: -------------------------------------------------------------------------------- 1 | provider "google" { 2 | version = "~> 3.0.0" 3 | project = var.gcp_project_id 4 | region = var.gcp_project_location 5 | } 6 | -------------------------------------------------------------------------------- /beginners/gcp/virtual-machine/variables.tf: -------------------------------------------------------------------------------- 1 | variable "gcp_project_id" { 2 | description = "This is a GCP Project id" 3 | type = string 4 | } 5 | 6 | variable "gcp_project_location" { 7 | description = "This is a GCP Project id" 8 | type = string 9 | } 10 | 11 | variable "machine_type" { 12 | description = "This is the type of the machine" 13 | type = string 14 | } 15 | 16 | variable "gcp_compute_zone" { 17 | description = "This is the zone in which the compute instances will be created" 18 | type = string 19 | } -------------------------------------------------------------------------------- /beginners/gcp/vpc/README.md: -------------------------------------------------------------------------------- 1 | ## Create a Google compute instance in GCP 2 | 3 | In this particular track, we are going to build a google cloud vpc using terrform. 4 | We will be binding an instance of VPC with a subnet and firewall rules. 5 | 6 | Add the necessary values of the variables in terraform.tfvars file or pass them as variables if you are using it as a module 7 | 8 | ``` 9 | vpc_name="" 10 | subnet_name="" 11 | gcp_project_id="" 12 | gcp_project_location="gcp-region" 13 | ip_cidr_range="10.1.0.0/24" 14 | ingress_ports=[80, 22, 8080] 15 | ``` 16 | 17 | ### Terraform Init 18 | 19 | This command will all the providers for you that are required to create your resource in GCP 20 | 21 | ```bash 22 | cd vpc 23 | terraform init 24 | ``` 25 | 26 | The CDN which servers the providers is quite slow that's why it can take some time for the providers to get downloaded 27 | 28 | ### Terraform plan 29 | 30 | This command will layout a plan for you and show you what all resources can be created 31 | 32 | ```bash 33 | cd vpc 34 | terraform plan 35 | ``` 36 | 37 | ### Terraform apply 38 | 39 | This command will create all the mentioned resources for yor 40 | 41 | ```bash 42 | cd vpc 43 | terraform apply 44 | ``` 45 | 46 | You'll be prompted a confirmation - Press yes. 47 | 48 | Once the resources have been created you should see 49 | 50 | ``` 51 | Apply complete! Resources: 0 added, 1 changed, 0 destroyed. 52 | 53 | Outputs: 54 | 55 | Apply complete! Resources: 3 added, 0 changed, 0 destroyed. 56 | 57 | Outputs: 58 | 59 | subnet_name = subnetes 60 | vpc_name = vpcs 61 | ``` 62 | -------------------------------------------------------------------------------- /beginners/gcp/vpc/firewall.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_firewall" "default" { 2 | name = "firewall-vpc-network" 3 | network = google_compute_network.this.self_link 4 | 5 | allow { 6 | protocol = "tcp" 7 | ports = var.ingress_ports 8 | } 9 | 10 | target_tags = ["http-server", "https-server"] 11 | } -------------------------------------------------------------------------------- /beginners/gcp/vpc/outputs.tf: -------------------------------------------------------------------------------- 1 | output "vpc_name" { 2 | value = google_compute_network.this.name 3 | } 4 | 5 | output "subnet_name" { 6 | value = google_compute_subnetwork.this.name 7 | } 8 | -------------------------------------------------------------------------------- /beginners/gcp/vpc/providers.tf: -------------------------------------------------------------------------------- 1 | provider "google" { 2 | version = "~> 3.0.0" 3 | project = var.gcp_project_id 4 | region = var.gcp_project_location 5 | } 6 | -------------------------------------------------------------------------------- /beginners/gcp/vpc/variables.tf: -------------------------------------------------------------------------------- 1 | variable "gcp_project_id" { 2 | description = "This is a GCP Project id" 3 | type = string 4 | } 5 | 6 | variable "gcp_project_location" { 7 | description = "This is a GCP Project id" 8 | type = string 9 | } 10 | 11 | variable "ip_cidr_range" { 12 | description = "This is the cidr range for subnet" 13 | type = string 14 | } 15 | 16 | variable "ingress_ports" { 17 | description = "This is the list of ports for vpc" 18 | type = list(string) 19 | } 20 | 21 | variable "subnet_name" { 22 | description = "This is the name that subnet gets" 23 | type = string 24 | } 25 | 26 | variable "vpc_name" { 27 | description = "This is the name that vpc gets" 28 | type = string 29 | } 30 | -------------------------------------------------------------------------------- /beginners/gcp/vpc/vpc.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_network" "this" { 2 | name = var.vpc_name 3 | auto_create_subnetworks = false 4 | } 5 | 6 | resource "google_compute_subnetwork" "this" { 7 | name = var.subnet_name 8 | ip_cidr_range = var.ip_cidr_range 9 | region = var.gcp_project_location 10 | network = google_compute_network.this.self_link 11 | private_ip_google_access = true 12 | } 13 | -------------------------------------------------------------------------------- /beginners/init-plan-apply/README.md: -------------------------------------------------------------------------------- 1 | # Terraform Init-Plan-Apply 2 | -------------------------------------------------------------------------------- /beginners/os/linux/README.md: -------------------------------------------------------------------------------- 1 | # Installing Terraform on Linux 2 | 3 | A binary distribution is avaialble for all environments. Let's grab the latest version of it for linux. 4 | 5 | ``` 6 | $ wget https://releases.hashicorp.com/terraform/0.12.26/terraform_0.12.26_linux_amd64.zip 7 | ``` 8 | 9 | Then unzip the archieve, 10 | 11 | ``` 12 | $ unzip terraform_0.12.26_linux_amd64.zip 13 | ``` 14 | 15 | Check the executable permission on the binary, if it's not executable, make it executable using the below commmand, 16 | 17 | ``` 18 | $ chmod +x terraform 19 | ``` 20 | 21 | Finally make sure that terrform is avaiable in PATH. So, let's move the binary into `/usr/local/bin` directroy, 22 | 23 | ``` 24 | $ sudo mv terraform /usr/local/bin 25 | ``` 26 | 27 | Now you are ready to run terraform commands. Open up a new termnal and run a command terraform and enter, 28 | 29 | ``` 30 | $ terraform 31 | ``` 32 | 33 | ## Verify the installation 34 | 35 | Verify that the installation worked by opening a new terminal session and listing Terraform's available subcommands. 36 | 37 | ``` 38 | $ terraform -help 39 | ``` 40 | 41 | ``` 42 | Usage: terraform [-version] [-help] [args] 43 | ``` 44 | 45 | The available commands for execution are listed below. 46 | The most common, useful commands are shown first, followed by 47 | less common or more advanced commands. If you're just getting 48 | started with Terraform, stick with the common commands. For the 49 | other commands, please read the help and docs before usage. 50 | ##... 51 | 52 | Add any subcommand to terraform -help to learn more about what it does and available options. 53 | 54 | ``` 55 | $ terraform -help plan 56 | ``` 57 | 58 | ## Troubleshoot 59 | 60 | If you get an error that terraform could not be found, your PATH environment variable was not set up properly. Please go back and ensure that your PATH variable contains the directory where Terraform was installed. 61 | 62 | ## Enable tab completion 63 | 64 | If you use either bash or zsh you can enable tab completion for Terraform commands. To enable autocomplete, run the following command and then restart your shell. 65 | 66 | ``` 67 | $ terraform -install-autocomplete 68 | ``` 69 | 70 | -------------------------------------------------------------------------------- /beginners/os/mac/README.md: -------------------------------------------------------------------------------- 1 | # Installing Terraform on MacOS 2 | 3 | Homebrew is a free and open-source package management system for Mac OS X. Install the Terraform formula from the terminal. 4 | 5 | ``` 6 | $ brew install terraform 7 | ``` 8 | 9 | NOTE: Homebrew and the Terraform formula are NOT directly maintained by HashiCorp. The latest version of Terraform is always available by manual installation. 10 | 11 | ## Verify the installation 12 | 13 | Verify that the installation worked by opening a new terminal session and listing Terraform's available subcommands. 14 | 15 | ``` 16 | $ terraform -help 17 | ``` 18 | 19 | ``` 20 | Usage: terraform [-version] [-help] [args] 21 | ``` 22 | 23 | The available commands for execution are listed below. 24 | The most common, useful commands are shown first, followed by 25 | less common or more advanced commands. If you're just getting 26 | started with Terraform, stick with the common commands. For the 27 | other commands, please read the help and docs before usage. 28 | ##... 29 | 30 | Add any subcommand to terraform -help to learn more about what it does and available options. 31 | 32 | ``` 33 | $ terraform -help plan 34 | ``` 35 | 36 | ## Troubleshoot 37 | 38 | If you get an error that terraform could not be found, your PATH environment variable was not set up properly. Please go back and ensure that your PATH variable contains the directory where Terraform was installed. 39 | 40 | ## Enable tab completion 41 | 42 | If you use either bash or zsh you can enable tab completion for Terraform commands. To enable autocomplete, run the following command and then restart your shell. 43 | 44 | ``` 45 | $ terraform -install-autocomplete 46 | ``` 47 | -------------------------------------------------------------------------------- /beginners/os/windows/README.md: -------------------------------------------------------------------------------- 1 | # Installing Terraform on Windows 2 | 3 | A binary distribution is avaialble for all environments. Let's grab the latest version of it for windows. 4 | 5 | Open up a powershell on your windows machine, cd to a directroy to D drive and create an Terraform directory, 6 | 7 | ``` 8 | PS C:\Users\user>D: 9 | ``` 10 | 11 | Get an exe from the below url, 12 | 13 | ``` 14 | PS D:\> curl.exe -O https://releases.hashicorp.com/terraform/0.12.26/terraform_0.12.26_windows_amd64.zip 15 | ``` 16 | 17 | Then unzip this archieve, rename a directory to terraform and we will see a single binary file name `terraform` and add it's path into environment variables. 18 | 19 | ``` 20 | PS D:\Terraform> Expand-Archive terraform_0.12.26_windows_amd64.zip 21 | PS D:\> Rename-Item -path .\terraform_0.12.26_windows_amd64\ .\terraform 22 | ``` 23 | 24 | Regarding setting up an environment variable, you can add terraform path in `Path` variable as shown in below screenshot, 25 | 26 | ![](/images/terraformenv.JPG) 27 | 28 | And, your are done. Now open up a terminal and run a command terrform and enter 29 | 30 | ``` 31 | PS D:\terraform> terraform 32 | 33 | ``` 34 | 35 | ## Verify the installation 36 | 37 | Verify that the installation worked by opening a new powershell or cmd session and listing Terraform's available subcommands. 38 | 39 | ``` 40 | PS D:\terraform> terraform -help 41 | ``` 42 | 43 | ``` 44 | Usage: terraform [-version] [-help] [args] 45 | ``` 46 | 47 | The available commands for execution are listed below. 48 | The most common, useful commands are shown first, followed by 49 | less common or more advanced commands. If you're just getting 50 | started with Terraform, stick with the common commands. For the 51 | other commands, please read the help and docs before usage. 52 | ##... 53 | 54 | Add any subcommand to terraform -help to learn more about what it does and available options. 55 | 56 | ``` 57 | PS D:\terraform> terraform -help plan 58 | ``` 59 | 60 | ## Troubleshoot 61 | 62 | If you get an error that terraform could not be found, your PATH environment variable was not set up properly. Please go back and ensure that your Path variable contains the directory where Terraform was installed. 63 | 64 | -------------------------------------------------------------------------------- /beginners/providers/Terraform_Providers.md: -------------------------------------------------------------------------------- 1 | # Terraform Providers 2 | In general, providers that are implemented as plugins(single binary) and the plugins/providers are the things that talk to the upstream APIs to make changes to the real infrastructure. Terraform uses a single provider, or multiple providers, to establish a connection to any services like IaaS, PaaS, or SaaS and provision resources. The provider is the first thing you need to set up before you can start creating resources for the vendor the provider is designed for. 3 | 4 | We will take infrastructure provider AWS as an example here. The AWS provider is designed to allow you to provision AWS resources, such as EC2 Instances or Security groups, against your AWS account. Without first declaring the provider, Terraform does not know about your account details, region, the security profile to use, and so on. 5 | 6 | Terraform’s documentation on providers can be found here: 7 | 8 | [Providers](https://www.terraform.io/docs/providers/index.html) 9 | 10 | ## AWS Provider 11 | We will focus on AWS for example. We’ll need to configure an AWS provider with our region, at minimum. 12 | A simple version of the AWS provider looks like this: 13 | 14 | ```hcl 15 | provider "aws" { 16 | region = "ap-south-1" 17 | } 18 | ``` 19 | The above code block is sufficient, if you have configured your AWS credentials locally ([Refer this link for more details](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)). 20 | 21 | AWS provider offers a different ways of passing credentials for authentication as below 22 | 23 | - Static credentials 24 | - Environment variables 25 | - Shared credentials file 26 | - EC2 Role (Will be covered in advanced track) 27 | 28 | ### Static credentials 29 | > **WARNING:** This is one of the supported method for authentication, but hard-coding is strictly NOT recommended. 30 | 31 | Using this method, you can pass the AWS **access_key** ID and **secret_key** within the provider code block as an argument. 32 | 33 | ```hcl 34 | provider "aws" { 35 | region = "ap-south-1" 36 | access_key = "AKIAXXXXXMPLE" 37 | secret_key = "wJalrXUtnXXXXXXXXKEY" 38 | } 39 | ``` 40 | 41 | ### Environment variables 42 | This method provide another way to specify configuration options and credentials. The following examples show how you can configure environment variables for the default user. 43 | 44 | ```hcl 45 | provider "aws" {} 46 | ``` 47 | 48 | **Linux or Mac:** 49 | ```bash 50 | export AWS_ACCESS_KEY_ID=AKIAXXXXXMPLE 51 | export AWS_SECRET_ACCESS_KEY=wJalrXUtnXXXXXXXXKEY 52 | export AWS_DEFAULT_REGION=ap-south-1 53 | ``` 54 | 55 | **Windows PowerShell:** 56 | ```powershell 57 | $Env:AWS_ACCESS_KEY_ID="AKIAXXXXXMPLE" 58 | $Env:AWS_SECRET_ACCESS_KEY="wJalrXUtnXXXXXXXXKEY" 59 | $Env:AWS_DEFAULT_REGION="ap-south-1" 60 | ``` 61 | Once you have exported the keys, you can run the terraform commands. 62 | 63 | 64 | ### Shared credentials file 65 | If you have [configured AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html) on your system earlier, credentials and default region informations will be stored in a plain-text under the default location of user's home directory `$HOME/.aws/credentials`. Terraform will check this location for the credentials. Optionally you can specify a different custom location by providing the `shared_credentials_file` argument 66 | 67 | ```hcl 68 | provider "aws" { 69 | region = "ap-south-1" 70 | shared_credentials_file = "/home/tf_user/creds" 71 | } 72 | ``` 73 | -------------------------------------------------------------------------------- /beginners/rds-restore/README.md: -------------------------------------------------------------------------------- 1 | # Creating an automated RDS (Amazon Relational Database Service) instance and implementing a restore strategy using Terraform 2 | 3 | A high-level overview of the steps involved, along with some guidance on troubleshooting the issues you're facing. 4 | Please note that this overview assumes you have some familiarity with Terraform and AWS services. 5 | 6 | 1. Set up the necessary AWS and Terraform configurations: 7 | 8 | - Ensure you have valid AWS credentials with appropriate permissions. 9 | - Install and configure Terraform on your local machine. 10 | - Create a new Terraform project directory and initialize it. 11 | 12 | 2. Define your Terraform configuration files: 13 | 14 | - Create a .tf file (e.g., main.tf) for your RDS instance configuration. 15 | - Specify the required AWS provider and region. 16 | - Define the RDS instance resource, specifying details such as engine, instance type, storage, etc. 17 | - Define any necessary security groups, subnets, and parameter groups. 18 | 19 | 3. Configure automatic backups and enable the backup retention period: 20 | 21 | - Specify the backup_retention_period for your RDS instance. 22 | - Enable automated backups by setting backup_window and maintenance_window parameters. 23 | 24 | 4. Implement the restore strategy: 25 | 26 | - Create a new .tf file for the restore configuration (e.g., restore.tf). 27 | - Define a new RDS instance resource using the restored snapshot ID. 28 | - Configure necessary settings like DB instance identifier, engine, instance type, security groups, etc. 29 | 30 | 5. Plan and apply your Terraform configuration: 31 | 32 | - Run terraform init to initialize your Terraform project. 33 | - Run terraform plan to verify the changes and ensure the configuration is correct. 34 | - Run terraform apply to create the RDS instance and implement the restore strategy. 35 | 36 | ## Getting Started 37 | 38 | To create the RDS instance and implement the restore strategy, follow these steps: 39 | 40 | - Install Terraform on your local machine. 41 | - Create a new directory for your Terraform project and place the main.tf and restore.tf files inside it. 42 | - Initialize the project by running terraform init in the project directory. 43 | - Review the Terraform plan by running terraform plan. It will show you the changes that Terraform will apply. 44 | - Apply the changes by running terraform apply. Terraform will create the RDS instance and implement the restore strategy using the specified snapshot. 45 | - Once the apply is complete, you should have your RDS instance created and the restore strategy implemented. 46 | -------------------------------------------------------------------------------- /beginners/rds-restore/main.tf: -------------------------------------------------------------------------------- 1 | # main.tf 2 | 3 | # Configure the AWS provider 4 | provider "aws" { 5 | region = "us-west-2" # Update with your desired region 6 | } 7 | 8 | # Define the RDS instance 9 | resource "aws_db_instance" "example" { 10 | engine = "mysql" 11 | instance_class = "db.t3.micro" 12 | allocated_storage = 20 13 | storage_type = "gp2" 14 | identifier = "my-rds-instance" 15 | username = "admin" 16 | password = "password" 17 | publicly_accessible = false 18 | 19 | # Other RDS configuration settings... 20 | 21 | # Enable automatic backups and set the retention period 22 | backup_retention_period = 7 23 | backup_window = "03:00-04:00" 24 | maintenance_window = "sun:05:00-sun:06:00" 25 | } 26 | -------------------------------------------------------------------------------- /beginners/rds-restore/restore.tf: -------------------------------------------------------------------------------- 1 | # restore.tf 2 | 3 | # Define the restored RDS instance 4 | resource "aws_db_instance" "restored_example" { 5 | engine = "mysql" 6 | instance_class = "db.t3.micro" 7 | allocated_storage = 20 8 | storage_type = "gp2" 9 | identifier = "restored-rds-instance" 10 | username = "admin" 11 | password = "password" 12 | publicly_accessible = false 13 | 14 | # Other RDS configuration settings... 15 | 16 | # Specify the snapshot ID to restore from 17 | snapshot_identifier = "" 18 | } 19 | -------------------------------------------------------------------------------- /beginners/resources/Terraform_Resources.md: -------------------------------------------------------------------------------- 1 | # Terraform Resources 2 | ## Component or Object 3 | Terraform has two different type of component/object 4 | - `resource` 5 | - `data` 6 | 7 | ### Resource: 8 | Resource are the daily bread of Terraform. They illustrate the infrastructure pieces that you want to manage such as networks, servers, firewalls, etc. Terraform will use the cloud provider APIs to perform the create, read, update, and delete(CRUD) operations. The `resource` object is constructed of a provider-name_resource-type, local identifier and the block containing the configuration of the resource. This would be better understood with the below diagram. 9 | 10 |

11 | 12 |

13 | 14 | All the resources are linked to a provider. From the above diagram, **`aws_instance`** indicates that this resource type is provided by the `aws` provider. Next is the local identifier name for the resource, which is specified by you, here we have named as `web` so that we can reference it elsewhere and Terraform keep track of it in the `.tfstate` file. Concept of `state` file will be covered in the upcoming tracks. 15 | 16 | See the below example code for the resource creation and how it is referenced to another piece of resource block. 17 | 18 | ```hcl 19 | resource "aws_instance" "collabnix_node" { 20 | ami = "ami-21f78e11" 21 | availability_zone = var.availability_zone 22 | instance_type = var.instance_type 23 | 24 | tags { 25 | Name = "Collabnix_terraform" 26 | } 27 | } 28 | 29 | resource "aws_ebs_volume" "collabnix_vol" { 30 | availability_zone = "us-east-1c" 31 | size = 1 32 | 33 | tags { 34 | Name = "Collabnix_terraform_vol" 35 | } 36 | } 37 | 38 | resource "aws_volume_attachment" "collabnix_vol_attachment" { 39 | device_name = "/dev/sdh" 40 | volume_id = aws_ebs_volume.collabnix_vol.id 41 | instance_id = aws_instance.collabnix_node.id 42 | } 43 | ``` 44 | 45 | From the above, we are creating a single EC2 instance, EBS volume, and attaching that volume to the instance. The first two resource blocks (EC2 instance & EBS volume) will be created independently. While trying to attach the volume to the instance, Terraform requires IDs of instance and volume to be attached. In this case you need to refer the local identifier name and the required attributes of the resources. See the below diagram for better understanding: 46 | 47 |

48 | 49 |

50 | 51 | Now terraform has enough information to take the necessary action. Here the `id` attributes are accessed using the dot-separated notation, like `aws_instance.collabnix_node.id`. Each type of resource will export thier own set of attribute values. Here, for example we used the `id` attribute. Refer this link for more details ([Attribute reference](https://www.terraform.io/docs/providers/aws/r/instance.html#attributes-reference)) 52 | 53 | ### Data sources: 54 | These are very similar to regular [resource](https://github.com/Raviadonis/terraform-1/blob/master/beginners/resources/README.md#resource) object which represents a piece of read-only information that can be fetched from the `provider` (here it is AWS) or from an [external](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) data source. This cannot be used for any operations like CREATE, UPDATE, or DELETE. Instead, they can only return several informations (meta-data) like AMI ID, Private IP, Instance ID and so on from an existing resources. 55 | 56 | ```hcl 57 | data "aws_ami" "app-ami" { 58 | most_recent = true 59 | owners = ["self"] 60 | } 61 | 62 | resource "aws_instance" "community" { 63 | ami = data.aws_ami.app-ami.id 64 | instance_type = "t2.micro" 65 | tags = { 66 | Name = "Collabnix" 67 | } 68 | } 69 | ``` 70 | From the above example code, we are creating an EC2 instance by using the existing AMI ID. Let's assume we have already created an AMI manually or with a different set of tools like `Packer`. Now terraform needs AMI-ID to create an instance and it fetches the ID from the data source `app-ami`. 71 | 72 | **Note:** 73 | The combination of resource type and the local identifier name must be unique in your configuration. The below configuration 74 | will through an error like: 75 | `aws_instance.collabnix_node: resource repeated multiple times` 76 | 77 | ```hcl 78 | resource "aws_instance" "collabnix_node" { 79 | ami = "ami-21f78e11" 80 | instance_type = var.instance_type 81 | } 82 | 83 | resource "aws_instance" "collabnix_node" { 84 | ami = "ami-21f78e11" 85 | instance_type = var.instance_type 86 | } 87 | ``` 88 | 89 | ## Arguments 90 | 91 | This is just a syntax of assining the vaules within the configuration blocks. It looks like the below 92 | ```hcl 93 | resource "aws_instance" "collabnix_node" { 94 | ami = "ami-21f78e11" # = 95 | instance_type = var.instance_type 96 | } 97 | ``` 98 | Each type of resources will have the list of supported arguments (required and optional) you can consume within your configuration blocks. 99 | 100 | Morover, you can also use the special kind of arguments called [meta-arguments](https://www.terraform.io/docs/configuration/resources.html#meta-arguments) within any type of resource. Primarily, these meta-arguments are used to change the behavior of the resource. See the list of meta-arguments below 101 | - `depends_on` 102 | - `count` 103 | - `for_each` 104 | - `provider` 105 | - `lifecycle` 106 | - `provisioner` 107 | - `connection` 108 | 109 | ```hcl 110 | resource "aws_instance" "collabnix_node" { 111 | depends_on = [aws_s3_bucket.collabnix_bucket] 112 | count = 2 113 | ami = "ami-21f78e11" 114 | instance_type = var.instance_type 115 | } 116 | 117 | resource "aws_s3_bucket" "collabnix_bucket" { 118 | bucket = "lab-bucket" 119 | acl = "private" 120 | versioning { 121 | enabled = true 122 | } 123 | tags { 124 | Name = "test-s3-terraform-bucket" 125 | } 126 | } 127 | ``` 128 | The above configuration blocks are just an example of how the meta-arguments can be used. Please do not go deeper and try to understand how it works in this beginner track. 129 | -------------------------------------------------------------------------------- /beginners/resources/variables/README.md: -------------------------------------------------------------------------------- 1 | # Terraform Variable Resources 2 | -------------------------------------------------------------------------------- /certification/1.Understand infrastructure as code (IaC) concepts/Questions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/certification/1.Understand infrastructure as code (IaC) concepts/Questions.md -------------------------------------------------------------------------------- /certification/2.Understand Terraform's purpose (vs other IaC)/Questions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/certification/2.Understand Terraform's purpose (vs other IaC)/Questions.md -------------------------------------------------------------------------------- /certification/3.Understand Terraform basics/Questions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/certification/3.Understand Terraform basics/Questions.md -------------------------------------------------------------------------------- /certification/4.Use the Terraform CLI (outside of core workflow)/Questions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/certification/4.Use the Terraform CLI (outside of core workflow)/Questions.md -------------------------------------------------------------------------------- /certification/5.Interact with Terraform modules/Questions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/certification/5.Interact with Terraform modules/Questions.md -------------------------------------------------------------------------------- /certification/6.Navigate Terraform workflow/Questions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/certification/6.Navigate Terraform workflow/Questions.md -------------------------------------------------------------------------------- /certification/7.Implement and maintain state/Questions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/certification/7.Implement and maintain state/Questions.md -------------------------------------------------------------------------------- /certification/8.Read, generate, and modify configuration/Questions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/certification/8.Read, generate, and modify configuration/Questions.md -------------------------------------------------------------------------------- /certification/9.Understand Terraform Cloud and Enterprise capabilities/Questions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/certification/9.Understand Terraform Cloud and Enterprise capabilities/Questions.md -------------------------------------------------------------------------------- /certification/README.md: -------------------------------------------------------------------------------- 1 | # Terraform Certification Guide 2 | 3 | The Terraform Associate certification is for Cloud Engineers specializing in operations, IT, or development who know the basic concepts and skills associated with open source HashiCorp Terraform. Candidates will be best prepared for this exam if they have professional experience using Terraform in production, but performing the exam objectives in a personal demo environment may also be sufficient. This person understands which enterprise features exist and what can and cannot be done using the open source offering. 4 | 5 | > **[The Official Terraform Certification Page](https://www.hashicorp.com/certification/terraform-associate/)** 6 | 7 | 8 | > **[The Official Terraform Certification Study Guide](https://learn.hashicorp.com/terraform/certification/terraform-associate-study-guide)** 9 | 10 | The exam objective has 9 modules. The questions will cover all the modules and you will get a scorecard for each module. The number of questions varies from a person to person. In my case, I got 57 questions. 11 | -------------------------------------------------------------------------------- /experts/README.md: -------------------------------------------------------------------------------- 1 | # Terraform Experts Track 2 | -------------------------------------------------------------------------------- /getting-started/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started - Terraform 2 | 3 | This section is all about how to get started with Terraform - what is it & why it is needed. 4 | 5 | Following topics are covered in this section: 6 | 7 | - [The problem of provisioning everything manually](the-problem.md) 8 | - [The concept of Infrastructure as a Code (IaC)](iac.md) 9 | - [Where terraform comes in?](terraform.md) 10 | - [Use cases of Terraform](use-cases.md) -------------------------------------------------------------------------------- /getting-started/iac.md: -------------------------------------------------------------------------------- 1 | # The Concept of Infrastructure as a Code (IaC) 2 | 3 | Infrastructure as a Code (IaC), as the name suggests, is a way of managing your entire infrastructure in the form of code. It helps us to solve several problems such as: 4 | 5 | 1. **Reproducible Environments:** By using code to generate infrastructure, the same environment can be created over and over. Over time an environment can drift away from its desired state and difficult to diagnose issues can creep into your release pipeline. With IaC no environment gets special treatment and fresh new environments are easily created and destroyed. 6 | 7 | 2. **Idempotence & Convergence:** In IaC, only the actions needed to bring the environment to the desired state are executed. If the environment is already in the desired state, no actions are taken. 8 | 9 | 3. **Easing Collaboration:** Having the code in a version control system like Git allows teams to collaborate on infrastructure. Team members can get specific versions of the code and create their own environments for testing or other scenarios. 10 | 11 | 4. **Self-service Infrastructure:** A pain point that often existed for developers before moving to cloud infrastructure was the delays required to have operations teams create the infrastructure they needed to build new features and tools. With the elasticity of the cloud allowing resources to be created on-demand, developers can provision the infrastructure they need when they need it. IaC further improves the situation by allowing developers to use infrastructure modules to create identical environments at any point in the application development lifecycle. The infrastructure modules could be created by operations and shared with developers freeing developers from having to learn another skill. 12 | 13 | All combined these benefits make IaC a staple in DevOps practices. 14 | 15 | *** 16 | 17 | [< Previous](the-problem.md) | [Next >](terraform.md) -------------------------------------------------------------------------------- /getting-started/terraform.md: -------------------------------------------------------------------------------- 1 | # Enter Terraform 2 | 3 | **Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently.** Terraform can manage existing and popular service providers as well as custom in-house solutions. 4 | 5 | Configuration files describe to Terraform the components needed to run a single application or your entire datacenter. Terraform generates an _execution plan_ describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans which can be applied. 6 | 7 | The infrastructure Terraform can manage includes low-level components such as compute instances, storage, and networking, as well as high-level components such as DNS entries, SaaS features, etc. 8 | 9 | Following are the key features of Terraform: 10 | 11 | 1. **Infrastructure as a Code:** As discussed earlier, Infrastructure is described using a high-level configuration syntax. This allows a blueprint of your datacenter to be versioned and treated as you would any other code. Additionally, infrastructure can be shared and re-used. 12 | 13 | 2. **Execution Plans:** Terraform has a "planning" step where it generates an _execution plan_. The execution plan shows what Terraform will do when you call apply. This lets you avoid any surprises when Terraform manipulates infrastructure. 14 | 15 | 3. **Resource Graph:** Terraform builds a graph of all your resources, and parallelizes the creation and modification of any non-dependent resources. Because of this, Terraform builds infrastructure as efficiently as possible, and operators get insight into dependencies in their infrastructure. 16 | 17 | 4. **Change Automation:** Complex changesets can be applied to your infrastructure with minimal human interaction. With the previously mentioned execution plan and resource graph, you know exactly what Terraform will change and in what order, avoiding many possible human errors. 18 | 19 | *** 20 | 21 | [< Previous](iac.md) | [Next >](use-cases.md) -------------------------------------------------------------------------------- /getting-started/the-problem.md: -------------------------------------------------------------------------------- 1 | # The problem of provisioning everything manually 2 | 3 | Whenever we have the need to setup any infrastructure we always tend to go towards the manual approach by clicking and going through the steps in the UI provided by the major public cloud provider (AWS, Azure, GCP), cloud provider (Linode, DigitalOcean etc.), DNS provider (CloudFlare, Route53, DNSimple etc.) and many such services. 4 | 5 | One way to approach this problem is to use scripts. But with that comes another set of challenges such as: 6 | 7 | - They're idiosyncratic - if I wrote a script, the other person might not be able to understand the steps being performed. 8 | - They're not idempotent - if I ran the script multiple times, it might not provide me the same result. 9 | - Compatibility issues - if I developed the script on a Linux machine, the other person who is using Windows might not be able to use the script and vice versa. 10 | - The scripts are only for one task. If you want to deploy something else, you need to develop them again. 11 | 12 | So, how to automate the setup process without having to deal with the hassles of developing a script? That's where the concept of Infrastructure as a Code (IaC) comes in. 13 | 14 | *** 15 | 16 | [Next >](iac.md) -------------------------------------------------------------------------------- /getting-started/use-cases.md: -------------------------------------------------------------------------------- 1 | # Use Cases of Terraform 2 | 3 | We can specify some use-cases which can help you with the applications of Terraform as an IaC solution: 4 | 5 | ## Heroku App Setup 6 | 7 | Terraform can be used to codify the setup required for a Heroku application, ensuring that all the required add-ons are available, but it can go even further: configuring DNSimple to set a CNAME, or setting up Cloudflare as a CDN for the app. Best of all, Terraform can do all of this in under 30 seconds without using a web interface. 8 | 9 | ## Multi-tier Applications 10 | 11 | A very common pattern is the N-tier architecture. The most common 2-tier architecture is a pool of web servers that use a database tier. Additional tiers get added for API servers, caching servers, routing meshes, etc. This pattern is used because the tiers can be scaled independently and provide a separation of concerns. 12 | 13 | Terraform is an ideal tool for building and managing these infrastructures. Each tier can be described as a collection of resources, and the dependencies between each tier are handled automatically; Terraform will ensure the database tier is available before the web servers are started and that the load balancers are aware of the web nodes. Each tier can then be scaled easily using Terraform by modifying a single `count` configuration value. Because the creation and provisioning of a resource is codified and automated, elastically scaling with load becomes trivial. 14 | 15 | ## Disposable Environments 16 | 17 | It is common practice to have both a production and staging or QA environment. These environments are smaller clones of their production counterpart, but are used to test new applications before releasing in production. As the production environment grows larger and more complex, it becomes increasingly onerous to maintain an up-to-date staging environment. 18 | 19 | Using Terraform, the production environment can be codified and then shared with staging, QA or dev. These configurations can be used to rapidly spin up new environments to test in, and then be easily disposed of. Terraform can help tame the difficulty of maintaining parallel environments, and makes it practical to elastically create and destroy them. 20 | 21 | ## Multi-cloud Deployments 22 | 23 | It's often attractive to spread infrastructure across multiple clouds to increase fault-tolerance. By using only a single region or cloud provider, fault tolerance is limited by the availability of that provider. Having a multi-cloud deployment allows for more graceful recovery of the loss of a region or entire provider. 24 | 25 | Realizing multi-cloud deployments can be very challenging as many existing tools for infrastructure management are cloud-specific. Terraform is cloud-agnostic and allows a single configuration to be used to manage multiple providers, and to even handle cross-cloud dependencies. This simplifies management and orchestration, helping operators build large-scale multi-cloud infrastructures. 26 | 27 | *** 28 | 29 | [< Previous](terraform.md) -------------------------------------------------------------------------------- /images/Azure_staticwebsite_Error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/Azure_staticwebsite_Error.png -------------------------------------------------------------------------------- /images/Azure_staticwebsite_Success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/Azure_staticwebsite_Success.png -------------------------------------------------------------------------------- /images/README.md: -------------------------------------------------------------------------------- 1 | # List of Images 2 | -------------------------------------------------------------------------------- /images/Terraform-Provisioners.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/Terraform-Provisioners.png -------------------------------------------------------------------------------- /images/TerraformVsDeployMgr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/TerraformVsDeployMgr.jpg -------------------------------------------------------------------------------- /images/Terraform_Resource_Identifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/Terraform_Resource_Identifier.png -------------------------------------------------------------------------------- /images/Terraform_Resource_definition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/Terraform_Resource_definition.png -------------------------------------------------------------------------------- /images/aws_website_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/aws_website_error.png -------------------------------------------------------------------------------- /images/aws_website_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/aws_website_success.png -------------------------------------------------------------------------------- /images/terraformenv.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/terraformenv.JPG -------------------------------------------------------------------------------- /images/wordle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/collabnix/terraform/1f1ada1abadac364572c008ffcc7026e79002a61/images/wordle.png -------------------------------------------------------------------------------- /intermediate/README.md: -------------------------------------------------------------------------------- 1 | # Terraform Intermediate Track 2 | 3 | ## Kubernetes 4 | 5 | - [Deploy Your EKS Cluster using Terraform](https://github.com/collabnix/terraform/blob/master/beginners/aws/README.md) 6 | 7 | 8 | ## Generic Terraform Related 9 | 10 | - [Terraform Functions](https://github.com/collabnix/terraform/blob/master/intermediate/Terraform-Functions) 11 | - Terraform Conditionals 12 | - Using Remote Backend 13 | - Terraform Provisioners 14 | - Multiple Providers 15 | 16 | -------------------------------------------------------------------------------- /intermediate/Terraform-Functions/All_Outputs.txt: -------------------------------------------------------------------------------- 1 | abs-output = { 2 | "float" = 13.25 3 | "negative" = 482 4 | "positive" = 13 5 | "zero" = 0 6 | } 7 | abspath-output = /Users/Vamsi/Desktop/Terraform/terraform/intermediate/Terraform-Functions 8 | ceil-output = { 9 | "op1" = 13 10 | "op2" = 13 11 | "op3" = 14 12 | "op4" = 14 13 | } 14 | cidrhost-output = { 15 | "IP1" = "10.0.0.8" 16 | "IP2" = "10.0.1.0" 17 | "IP3" = "10.0.1.12" 18 | } 19 | cidrsubnet-output = { 20 | "App-Subnet" = "10.0.2.0/24" 21 | "DB-Subnet" = "10.0.3.0/24" 22 | "Web-Subnet" = "10.0.1.0/24" 23 | } 24 | cidrsubnets-output = { 25 | "Dev-Subnets" = [ 26 | "10.0.0.0/24", 27 | "10.0.1.0/24", 28 | "10.0.2.0/24", 29 | "10.0.3.0/24", 30 | ] 31 | "Prod-Subnets" = [ 32 | "10.0.0.0/20", 33 | "10.0.16.0/20", 34 | "10.0.32.0/24", 35 | "10.0.48.0/20", 36 | ] 37 | } 38 | concat-output = [ 39 | "collbnix", 40 | "is", 41 | "an", 42 | "awesome", 43 | "group", 44 | ] 45 | distinct-output = [ 46 | "aws", 47 | "azure", 48 | "gcp", 49 | "k8s", 50 | ] 51 | element-output = { 52 | "0" = "collabnix" 53 | "1" = "aws" 54 | "2" = "azure" 55 | "3" = "gcp" 56 | "4" = "k8s" 57 | } 58 | file-output = # Output of file function 59 | Collabnix Rocks !!! 60 | fileexists-output = { 61 | "Doesnt_Exist" = false 62 | "Exists" = true 63 | } 64 | floor-output = { 65 | "op1" = 13 66 | "op2" = 13 67 | "op3" = 13 68 | "op4" = 13 69 | } 70 | join-output = collabnix-terraform-aws-azure-gpc 71 | length-output = { 72 | "length-list" = 5 73 | "length-map" = 3 74 | "length-null" = 0 75 | "length-string" = 9 76 | } 77 | log-output = { 78 | "op1" = 3.3219280948873626 79 | "op2" = 2 80 | } 81 | lookup-output = { 82 | "Key_Doesnt_Exist" = "GettingBetter" 83 | "Key_Exists" = "Better" 84 | } 85 | lower-output = collabnix 86 | max-output = 1325 87 | min-output = 13 88 | pathexpand-output = /Users/Vamsi/file1.txt 89 | pow-output = { 90 | "op1" = 169 91 | "op2" = 1 92 | "op3" = 0 93 | "op4" = 1 94 | } 95 | replace-output = us-west-1 96 | setproduct-output = [ 97 | [ 98 | "Aws", 99 | "Certified", 100 | "Associate", 101 | ], 102 | [ 103 | "Aws", 104 | "Certified", 105 | "Professional", 106 | ], 107 | [ 108 | "Azure", 109 | "Certified", 110 | "Associate", 111 | ], 112 | [ 113 | "Azure", 114 | "Certified", 115 | "Professional", 116 | ], 117 | [ 118 | "Gcp", 119 | "Certified", 120 | "Associate", 121 | ], 122 | [ 123 | "Gcp", 124 | "Certified", 125 | "Professional", 126 | ], 127 | ] 128 | signum-output = { 129 | "op1" = 0 130 | "op2" = 1 131 | "op3" = -1 132 | } 133 | slice-output = [ 134 | "terraform", 135 | "aws", 136 | "azure", 137 | ] 138 | sort-outputs = { 139 | "sort-list1" = [ 140 | "aws", 141 | "azure", 142 | "collabnix", 143 | "gpc", 144 | "terraform", 145 | ] 146 | "sort-list3" = [ 147 | "13", 148 | "19", 149 | "25", 150 | "27", 151 | "482", 152 | ] 153 | "sort_list2" = [ 154 | "", 155 | "a", 156 | "b", 157 | "c", 158 | "d", 159 | ] 160 | } 161 | split-output = [ 162 | "collabnix", 163 | "terraform", 164 | "aws", 165 | "azure", 166 | "gpc", 167 | ] 168 | substr-output = oll 169 | templatefile-output = Ip Address with port 170 | 10.0.10.0:443 171 | upper-output = COLLABNIX 172 | zipmap-output = { 173 | "Aws" = 1 174 | "Azure" = 2 175 | "Gcp" = 3 176 | } 177 | -------------------------------------------------------------------------------- /intermediate/Terraform-Functions/FileSystem_Functions.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*# 2 | #* Terraform Functions - File System Functions *# 3 | #*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*# 4 | 5 | #-------------------------------------------------------------------------------------------------------------------- 6 | # abspath() 7 | # Takes a string containing a filesystem path and converts it to an absolute path. 8 | # That is, if the path is not absolute, it will be joined with the current working directory. 9 | # Syntax: abspath() 10 | #-------------------------------------------------------------------------------------------------------------------- 11 | 12 | output "abspath-output" { 13 | description = "Print the output of abspath function" 14 | value = abspath(path.root) 15 | } 16 | 17 | 18 | #-------------------------------------------------------------------------------------------------------------------- 19 | # file() 20 | # Reads the contents of a file at the given path and returns them as a string. 21 | # Syntax: file(path) 22 | #-------------------------------------------------------------------------------------------------------------------- 23 | 24 | output "file-output" { 25 | description = "Print the output of file function" 26 | value = file("./file1.txt") 27 | } 28 | 29 | 30 | #-------------------------------------------------------------------------------------------------------------------- 31 | # fileexits() 32 | # Determines whether a file exists at a given path. 33 | # Syntax: fileexists(path) 34 | #-------------------------------------------------------------------------------------------------------------------- 35 | 36 | output "fileexists-output" { 37 | description = "Print the output of fileexists function" 38 | value = { 39 | "Exists" = fileexists("./file1.txt") 40 | "Doesnt_Exist" = fileexists("./nofile.txt") 41 | } 42 | } 43 | 44 | #-------------------------------------------------------------------------------------------------------------------- 45 | # pathexpand() 46 | # Takes a filesystem path that might begin with a ~ segment, and if so it replaces that segment with the current user's home directory path. 47 | # Syntax: pathexpand(filenamewithpath) 48 | # More info at https://www.terraform.io/docs/configuration/functions/pathexpand.html 49 | #-------------------------------------------------------------------------------------------------------------------- 50 | 51 | output "pathexpand-output" { 52 | description = "Print the output of pathexpand function" 53 | value = pathexpand("~/file1.txt") 54 | } 55 | 56 | #-------------------------------------------------------------------------------------------------------------------- 57 | # templatefile() 58 | # Reads the file at the given path and renders its content as a template using a supplied set of template variables. 59 | # Syntax: templatefile(path, vars) 60 | # More info at https://www.terraform.io/docs/configuration/functions/templatefile.html 61 | #-------------------------------------------------------------------------------------------------------------------- 62 | 63 | output "templatefile-output" { 64 | description = "Print the output of templatefile function" 65 | value = templatefile("./output.tmpl", {ip_address = "10.0.10.0", port = 443}) 66 | } -------------------------------------------------------------------------------- /intermediate/Terraform-Functions/IP_Network_Functions.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*# 2 | #* Terraform Functions - IP Network Functions *# 3 | #*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*# 4 | 5 | #-------------------------------------------------------------------------------------------------------------------- 6 | # cidrsubnet() 7 | # Calculates a subnet address within given IP network address prefix. 8 | # Syntax: cidrsubnet(prefix, newbits, netnum) 9 | # More Info at https://www.terraform.io/docs/configuration/functions/cidrsubnet.html 10 | #-------------------------------------------------------------------------------------------------------------------- 11 | 12 | variable "vpc-cidr" { 13 | description = "Address range of Aws VPC/Azure Vnet" 14 | type = string 15 | default = "10.0.0.0/16" 16 | } 17 | 18 | output "cidrsubnet-output" { 19 | description = "Print the output of cidrsubnet function" 20 | value = { 21 | "Web-Subnet" = cidrsubnet(var.vpc-cidr, 8, 1) 22 | "App-Subnet" = cidrsubnet(var.vpc-cidr, 8, 2) 23 | "DB-Subnet" = cidrsubnet(var.vpc-cidr, 8, 3) 24 | } 25 | } 26 | 27 | #-------------------------------------------------------------------------------------------------------------------- 28 | # cidrsubnets() 29 | # Calculates a sequence of consecutive IP address ranges within a particular CIDR prefix. 30 | # Syntax: cidrsubnets(prefix, newbits...) 31 | # More Info at https://www.terraform.io/docs/configuration/functions/cidrsubnets.html 32 | #-------------------------------------------------------------------------------------------------------------------- 33 | 34 | output "cidrsubnets-output" { 35 | description = "Print the output of cidrsubnets function" 36 | value = { 37 | "Dev-Subnets" = cidrsubnets(var.vpc-cidr, 8, 8, 8, 8) 38 | "Prod-Subnets" = cidrsubnets(var.vpc-cidr, 4, 4, 8, 4) 39 | } 40 | } 41 | 42 | #-------------------------------------------------------------------------------------------------------------------- 43 | # cidrhost() 44 | # Calculates a full host IP address for a given host number within a given IP network address prefix. 45 | # Syntax: cidrhost(prefix, hostnum) 46 | # More Info at https://www.terraform.io/docs/configuration/functions/cidrhost.html 47 | #-------------------------------------------------------------------------------------------------------------------- 48 | 49 | output "cidrhost-output" { 50 | description = "Print the output of cidrhost function" 51 | value = { 52 | "IP1" = cidrhost(var.vpc-cidr, 8) 53 | "IP2" = cidrhost(var.vpc-cidr, 256) 54 | "IP3" = cidrhost(var.vpc-cidr, 268) 55 | } 56 | } -------------------------------------------------------------------------------- /intermediate/Terraform-Functions/Numeric_Functions.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Terraform Functions - Numeric Functions *# 3 | #*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | 6 | #-------------------------------------------------------------------------------------------------------------------- 7 | # abs() 8 | # returns the absolute value of the given number. In other words, if the number is zero or positive then it is returned as-is, but if it is negative then it is multiplied by -1 to make it positive before returning it. 9 | # Syntax: abs(number) 10 | #-------------------------------------------------------------------------------------------------------------------- 11 | 12 | 13 | output "abs-output" { 14 | description = "Print the output of abs function" 15 | value = { 16 | "positive" = abs(13) 17 | "zero" = abs(0) 18 | "negative" = abs(-482) 19 | "float" = abs(-13.25) 20 | } 21 | } 22 | 23 | # Interesting Observation: if you uncomment the below output, Terraform will crash because it cant serialize infinity(1/0) as Json. 24 | 25 | // output "tf-crash" { 26 | // value = abs(1/0) 27 | // } 28 | 29 | 30 | #-------------------------------------------------------------------------------------------------------------------- 31 | # ceil() 32 | # Returns the closest whole number that is greater than or equal to the given value, which may be a fraction. 33 | # Syntax: ceil(number) 34 | #-------------------------------------------------------------------------------------------------------------------- 35 | 36 | 37 | output "ceil-output" { 38 | description = "Print the output of ceil function" 39 | value = { 40 | "op1" = ceil(13) 41 | "op2" = ceil(13.0) 42 | "op3" = ceil(13.1) 43 | "op4" = ceil(13.99999) 44 | } 45 | } 46 | 47 | 48 | #-------------------------------------------------------------------------------------------------------------------- 49 | # floor() 50 | # Returns the closest whole number that is less than or equal to the given value, which may be a fraction. 51 | # Syntax: floor(number) 52 | #-------------------------------------------------------------------------------------------------------------------- 53 | 54 | 55 | output "floor-output" { 56 | description = "Print the output of floor function" 57 | value = { 58 | "op1" = floor(13) 59 | "op2" = floor(13.0) 60 | "op3" = floor(13.1) 61 | "op4" = floor(13.99999) 62 | } 63 | } 64 | 65 | 66 | #-------------------------------------------------------------------------------------------------------------------- 67 | # log() 68 | # Returns the logarithm of a given number in a given base. 69 | # Syntax: log(number, base) 70 | #-------------------------------------------------------------------------------------------------------------------- 71 | 72 | 73 | output "log-output" { 74 | description = "Print the output of log function" 75 | value = { 76 | "op1" = log(10,2) 77 | "op2" = log(16,4) 78 | } 79 | } 80 | 81 | #-------------------------------------------------------------------------------------------------------------------- 82 | # max() 83 | # Takes one or more numbers and returns the greatest number from the set. 84 | # Syntax: max(number1, number2, ...) 85 | #-------------------------------------------------------------------------------------------------------------------- 86 | 87 | 88 | output "max-output" { 89 | description = "Print the output of max function" 90 | value = max(13, 25, 0, 1325, 482, 27, 19) 91 | } 92 | 93 | 94 | #-------------------------------------------------------------------------------------------------------------------- 95 | # min() 96 | # Takes one or more numbers and returns the smallest number from the set. 97 | # Syntax: min(number1, number2, ...) 98 | #-------------------------------------------------------------------------------------------------------------------- 99 | 100 | 101 | output "min-output" { 102 | description = "Print the output of min function" 103 | value = min(13, 25, 1325, 482, 27, 19) 104 | } 105 | 106 | #-------------------------------------------------------------------------------------------------------------------- 107 | # pow() 108 | # Calculates an exponent, by raising its first argument to the power of the second argument. 109 | # Syntax: pow(number1, number2) 110 | #-------------------------------------------------------------------------------------------------------------------- 111 | 112 | 113 | output "pow-output" { 114 | description = "Print the output of pow function" 115 | value = { 116 | "op1" = pow(13,2) 117 | "op2" = pow(5,0) 118 | "op3" = pow(0,5) 119 | "op4" = pow(0,0) 120 | } 121 | } 122 | 123 | #-------------------------------------------------------------------------------------------------------------------- 124 | # signum() 125 | # Determines the sign of a number, returning a number between -1 and 1 to represent the sign. 126 | # Syntax: signum(number) 127 | #-------------------------------------------------------------------------------------------------------------------- 128 | 129 | 130 | output "signum-output" { 131 | description = "Print the output of signum function" 132 | value = { 133 | "op1" = signum(0) 134 | "op2" = signum(13) 135 | "op3" = signum(-13) 136 | } 137 | } -------------------------------------------------------------------------------- /intermediate/Terraform-Functions/String_Collection_Functions.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 2 | #* Terraform Functions - String and Collection Functions *# 3 | #*#*#*#*#*#*#*#*##*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# 4 | 5 | 6 | #-------------------------------------------------------------------------------------------------------------------- 7 | # lower() 8 | # Converts all cased letters in the given string to lowercase. 9 | # Syntax: lower(string) 10 | #-------------------------------------------------------------------------------------------------------------------- 11 | 12 | 13 | variable "lower_var" { 14 | description = "Example of lower function in Terraform" 15 | type = string 16 | default = "COLLABNIX" 17 | } 18 | 19 | output "lower-output" { 20 | description = "Print the variable in lowercase" 21 | value = lower(var.lower_var) 22 | } 23 | 24 | 25 | #-------------------------------------------------------------------------------------------------------------------- 26 | # upper() 27 | # Converts all cased letters in the given string to uppercase. 28 | # Syntax: upper(string) 29 | #-------------------------------------------------------------------------------------------------------------------- 30 | 31 | variable "upper_var" { 32 | description = "Example of upper function in Terraform" 33 | type = string 34 | default = "collabnix" 35 | } 36 | 37 | output "upper-output" { 38 | description = "Print the variable in uppercase" 39 | value = upper(var.upper_var) 40 | } 41 | 42 | 43 | #-------------------------------------------------------------------------------------------------------------------- 44 | # split() --> 45 | # Produces a list by dividing a given string at all occurrences of a given separator. 46 | # Syntax: split(delimiter, string) 47 | #-------------------------------------------------------------------------------------------------------------------- 48 | 49 | variable "split_var" { 50 | description = "Example of split function in Terraform" 51 | type = string 52 | default = "collabnix,terraform,aws,azure,gpc" 53 | } 54 | 55 | output "split-output" { 56 | description = "Print the output of split function" 57 | value = split(",",var.split_var) 58 | } 59 | 60 | 61 | #-------------------------------------------------------------------------------------------------------------------- 62 | # replace() 63 | # Searches a given string for another given substring, and replaces each occurrence with a given replacement string. 64 | # Syntax: replace(string, search, replace) 65 | #-------------------------------------------------------------------------------------------------------------------- 66 | 67 | variable "replace_var" { 68 | description = "Example of replace function in Terraform" 69 | type = string 70 | default = "us-east-1" 71 | } 72 | 73 | output "replace-output" { 74 | description = "Print the output of replace function" 75 | value = replace(var.replace_var, "east", "west") 76 | } 77 | 78 | 79 | #-------------------------------------------------------------------------------------------------------------------- 80 | # substr() 81 | # Extracts a substring from a given string by offset and length. 82 | # Syntax: substr(string, offset, length) 83 | #-------------------------------------------------------------------------------------------------------------------- 84 | 85 | variable "substr_var" { 86 | description = "Example of replace function in Terraform" 87 | type = string 88 | default = "collabnix" 89 | } 90 | 91 | output "substr-output" { 92 | description = "Print the output of replace function" 93 | value = substr(var.substr_var, 1, 3) 94 | } 95 | 96 | 97 | #-------------------------------------------------------------------------------------------------------------------- 98 | # concat() 99 | # Takes two or more lists and combines them into a single list. 100 | # Syntax: concat(list1,list2,list3,...) 101 | #-------------------------------------------------------------------------------------------------------------------- 102 | 103 | 104 | variable "list1" { 105 | description = "Example of concat function in Terraform" 106 | type = list(string) 107 | default = ["collbnix","is"] 108 | } 109 | 110 | variable "list2" { 111 | description = "Example of concat function in Terraform" 112 | type = list(string) 113 | default = ["an","awesome","group"] 114 | } 115 | 116 | output "concat-output" { 117 | description = "Print the output of concat function" 118 | value = concat(var.list1,var.list2) 119 | } 120 | 121 | 122 | #-------------------------------------------------------------------------------------------------------------------- 123 | # distinct() 124 | # Takes a list and returns a new list with any duplicate elements removed. 125 | # Syntax: distinct(list) 126 | #-------------------------------------------------------------------------------------------------------------------- 127 | 128 | 129 | variable "distinct_var" { 130 | description = "Example of distinct function in Terraform" 131 | type = list(string) 132 | default = ["aws","aws","azure","gcp","aws","azure","k8s"] 133 | } 134 | 135 | output "distinct-output" { 136 | description = "Print the output of distinct function" 137 | value = distinct(var.distinct_var) 138 | } 139 | 140 | 141 | #-------------------------------------------------------------------------------------------------------------------- 142 | # element() 143 | # Retrieves a single element from a list. 144 | # Syntax: element(list,index) 145 | #-------------------------------------------------------------------------------------------------------------------- 146 | 147 | variable "element_var" { 148 | description = "Example of element function in Terraform" 149 | type = list(string) 150 | default = ["collabnix", "aws", "azure", "gcp", "k8s"] 151 | } 152 | 153 | output "element-output" { 154 | description = "Map the index with its value" 155 | value = { 156 | 0 = element(var.element_var, 0) 157 | 1 = element(var.element_var, 1) 158 | 2 = element(var.element_var, 2) 159 | 3 = element(var.element_var, 3) 160 | 4 = element(var.element_var, 4) 161 | } 162 | } 163 | 164 | 165 | #-------------------------------------------------------------------------------------------------------------------- 166 | # join() 167 | # Produces a string by concatenating together all elements of a given list of strings with the given delimiter. 168 | # Syntax: join(delimiter,list) 169 | #-------------------------------------------------------------------------------------------------------------------- 170 | 171 | variable "join_list" { 172 | description = "Example of join function in Terraform" 173 | type = list(string) 174 | default = ["collabnix","terraform","aws","azure","gpc"] 175 | } 176 | 177 | output "join-output" { 178 | description = "Print the output of join function" 179 | value = join("-", var.join_list) 180 | } 181 | 182 | 183 | #-------------------------------------------------------------------------------------------------------------------- 184 | # length() 185 | # Determines the length of a given list, map, or string. 186 | # Syntax: length(value) 187 | #-------------------------------------------------------------------------------------------------------------------- 188 | 189 | variable "length_str" { 190 | description = "Example of length of a string" 191 | type = string 192 | default = "Collabnix" 193 | } 194 | 195 | variable "length_list" { 196 | description = "Example of length of a list" 197 | type = list(string) 198 | default = ["collabnix","terraform","aws","azure","gpc"] 199 | } 200 | 201 | variable "length_map" { 202 | description = "Example of length of a map" 203 | type = map(string) 204 | default = { 205 | "aws" = 1 206 | "azure" = 2 207 | "gcp" = 3 208 | } 209 | } 210 | 211 | variable "length_null" { 212 | description = "Example of length of a null string" 213 | type = string 214 | default = "" 215 | } 216 | 217 | output "length-output" { 218 | description = "Print the output of length function" 219 | value = { 220 | 221 | length-string = length(var.length_str) 222 | length-list = length(var.length_list) 223 | length-map = length(var.length_map) 224 | length-null = length(var.length_null) 225 | } 226 | } 227 | 228 | 229 | #-------------------------------------------------------------------------------------------------------------------- 230 | # slice() 231 | # Extracts some consecutive elements from within a list. 232 | # Syntax: slice(list, startindex, endindex) 233 | #-------------------------------------------------------------------------------------------------------------------- 234 | 235 | variable "slice_var" { 236 | description = "Example of Slice function in Terraform" 237 | type = list(string) 238 | default = ["collabnix","terraform","aws","azure","gpc"] 239 | } 240 | 241 | output "slice-output" { 242 | description = "Print the output of Slice function" 243 | value = slice(var.slice_var, 1, 4) 244 | } 245 | 246 | #-------------------------------------------------------------------------------------------------------------------- 247 | # sort() 248 | # Sorts a list in lexicographical order. 249 | # Syntax: sort(list) 250 | #-------------------------------------------------------------------------------------------------------------------- 251 | 252 | variable "sort_list1" { 253 | description = "Example of sort function in Terraform" 254 | type = list(string) 255 | default = ["collabnix", "terraform", "aws", "azure", "gpc"] 256 | } 257 | 258 | variable "sort_list2" { 259 | description = "Example of Slice function in Terraform" 260 | type = list(string) 261 | default = ["d", "a", "c", "b", ""] 262 | } 263 | 264 | variable "sort_list3" { 265 | description = "Example of Slice function in Terraform" 266 | type = list(number) 267 | default = [482, 13, 25, 27, 19] 268 | } 269 | 270 | output "sort-outputs" { 271 | description = "Print the output of sort function" 272 | value = { 273 | sort-list1 = sort(var.sort_list1) 274 | sort_list2 = sort(var.sort_list2) 275 | sort-list3 = sort(var.sort_list3) 276 | } 277 | } 278 | 279 | 280 | #-------------------------------------------------------------------------------------------------------------------- 281 | # lookup() 282 | # Retrieves the value of a single element from a map, given its key. 283 | # If the given key does not exist, a the given default value is returned instead. 284 | # Syntax: lookup(map, key, default) 285 | #-------------------------------------------------------------------------------------------------------------------- 286 | 287 | variable "map1" { 288 | description = "Example of lookup function in Terraform" 289 | type = map(string) 290 | default = { 291 | "Aws" = "Best" 292 | "Azure" = "Better" 293 | "Gcp" = "Good" 294 | } 295 | } 296 | 297 | output "lookup-output" { 298 | description = "Print the output of lookup function" 299 | value = { 300 | Key_Exists = lookup(var.map1, "Azure", "Default") 301 | Key_Doesnt_Exist = lookup(var.map1, "Oracle", "GettingBetter") 302 | } 303 | } 304 | 305 | #-------------------------------------------------------------------------------------------------------------------- 306 | # setproduct() 307 | # setproduct function finds all of the possible combinations of elements from all of the given sets by computing the Cartesian product. 308 | # Syntax: setproduct(sets...) 309 | #-------------------------------------------------------------------------------------------------------------------- 310 | 311 | output "setproduct-output" { 312 | description = "Print the output of setproduct function" 313 | value = setproduct(["Aws", "Azure", "Gcp"], ["Certified"], ["Associate", "Professional"]) 314 | } 315 | 316 | 317 | #-------------------------------------------------------------------------------------------------------------------- 318 | # zipmap() 319 | # Constructs a map from a list of keys and a corresponding list of values. 320 | # Both keyslist and valueslist must be of the same length. keyslist must be a list of strings, while valueslist can be a list of any type. 321 | # Syntax: zipmap(keyslist, valueslist) 322 | #-------------------------------------------------------------------------------------------------------------------- 323 | 324 | output "zipmap-output" { 325 | description = "Print the output of zipmap function" 326 | value = zipmap(["Aws", "Azure", "Gcp"], [1, 2, 3]) 327 | } 328 | 329 | -------------------------------------------------------------------------------- /intermediate/Terraform-Functions/file1.txt: -------------------------------------------------------------------------------- 1 | # Output of file function 2 | Collabnix Rocks !!! -------------------------------------------------------------------------------- /intermediate/Terraform-Functions/output.tmpl: -------------------------------------------------------------------------------- 1 | Ip Address with port 2 | ${ip_address}:${port} -------------------------------------------------------------------------------- /intermediate/azure/Terraform-Provisioners/README.md: -------------------------------------------------------------------------------- 1 | # Terraform Provisioners example 2 | 3 | - [Terraform Provisioners Official Documentation](https://www.terraform.io/docs/provisioners/index.html) 4 | 5 | - **Local-Exec Provisioner** - The local-exec provisioner invokes a local executable after a resource is created. This invokes a process on the machine running Terraform, not on the resource. 6 | 7 | - **Remote-Exec Provisioner** - The remote-exec provisioner invokes a script on a remote resource after it is created. This can be used to run a configuration management tool, bootstrap into a cluster, etc. The remote-exec provisioner supports both ssh and winrm type connections. 8 | 9 | 10 | **This module creates a linux virtual machine (UBUNTU 16.04)** 11 | 12 | > Note 1: This deployment is not free. If you are not on a free trail, it will incur a very small fee. So, its always a good practice to cleanup everything when you are done with the demo. 13 | 14 | > Note 2: We are creating a public IP address and attaching it to the VM to login via SSH. This is not a best practice and not recommended at all in a real production environment. So, please destroy the infrastructure after the demo. 15 | 16 | ## Changes you need to make before execution 17 | 18 | - In **azurerm_network_security_group** resource, paste in your local IP Address in *source_address_prefix*. This will restrict SSH access to your machine. Click [here](https://www.whatsmyip.org/) to findout your local ip address. 19 | 20 | ## Resources in this module 21 | 22 | - A Resource Group 23 | - A Virtual network with a Subnet 24 | - A Network Security Group 25 | - Subnet and NSG Association 26 | - A Public IP Address 27 | - A Network Interface 28 | - A Linux Virtual Machine - (Local-exec and Remote-exec provisioners) 29 | 30 | ## Provisioners Run 31 | 32 | 33 | ![Provisioners-Run](https://github.com/collabnix/terraform/blob/master/images/Terraform-Provisioners.png) 34 | 35 | ## After the deployment 36 | 37 | - Once the deployment is successful, you can login to the virtual machine. Login to the portal, go to the VM and click on Connect and select SSH. 38 | 39 | > DO NOT FORGET to cleanup everything with **$ terraform destroy -auto-approve** 40 | 41 | -------------------------------------------------------------------------------- /intermediate/azure/Terraform-Provisioners/linuxvm.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 2 | # Create a Linux VM and Run provisioners 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 4 | 5 | # 6 | # - Provider Block 7 | # 8 | 9 | provider "azurerm" { 10 | client_id = var.client_id 11 | client_secret = var.client_secret 12 | subscription_id = var.subscription_id 13 | tenant_id = var.tenant_id 14 | 15 | features {} 16 | } 17 | 18 | # 19 | # - Create a Resource Group 20 | # 21 | 22 | resource "azurerm_resource_group" "rg" { 23 | name = "${var.prefix}-rg" 24 | location = var.location 25 | tags = var.tags 26 | } 27 | 28 | # 29 | # - Create a Virtual Network 30 | # 31 | 32 | resource "azurerm_virtual_network" "vnet" { 33 | name = "${var.prefix}-vnet" 34 | resource_group_name = azurerm_resource_group.rg.name 35 | location = azurerm_resource_group.rg.location 36 | address_space = [var.vnet_address_range] 37 | tags = var.tags 38 | } 39 | 40 | # 41 | # - Create a Subnet inside the virtual network 42 | # 43 | 44 | resource "azurerm_subnet" "web" { 45 | name = "${var.prefix}-web-subnet" 46 | resource_group_name = azurerm_resource_group.rg.name 47 | virtual_network_name = azurerm_virtual_network.vnet.name 48 | address_prefixes = [var.subnet_address_range] 49 | } 50 | 51 | # 52 | # - Create a Network Security Group 53 | # 54 | 55 | resource "azurerm_network_security_group" "nsg" { 56 | name = "${var.prefix}-web-nsg" 57 | resource_group_name = azurerm_resource_group.rg.name 58 | location = azurerm_resource_group.rg.location 59 | tags = var.tags 60 | 61 | security_rule { 62 | name = "Allow_SSH" 63 | priority = 1000 64 | direction = "Inbound" 65 | access = "Allow" 66 | protocol = "Tcp" 67 | source_port_range = "*" 68 | destination_port_range = 22 69 | source_address_prefix = "PASTE_YOUR_LOCAL_IP" 70 | destination_address_prefix = "*" 71 | } 72 | } 73 | 74 | 75 | # 76 | # - Subnet-NSG Association 77 | # 78 | 79 | resource "azurerm_subnet_network_security_group_association" "subnet-nsg" { 80 | subnet_id = azurerm_subnet.web.id 81 | network_security_group_id = azurerm_network_security_group.nsg.id 82 | } 83 | 84 | 85 | # 86 | # - Public IP (To Login to Linux VM) 87 | # 88 | 89 | resource "azurerm_public_ip" "pip" { 90 | name = "${var.prefix}-linuxvm-public-ip" 91 | resource_group_name = azurerm_resource_group.rg.name 92 | location = azurerm_resource_group.rg.location 93 | allocation_method = var.allocation_method[0] 94 | tags = var.tags 95 | } 96 | 97 | # 98 | # - Create a Network Interface Card for Virtual Machine 99 | # 100 | 101 | resource "azurerm_network_interface" "nic" { 102 | name = "${var.prefix}-linuxvm-nic" 103 | resource_group_name = azurerm_resource_group.rg.name 104 | location = azurerm_resource_group.rg.location 105 | tags = var.tags 106 | ip_configuration { 107 | name = "linuxvm-nic-ipconfig" 108 | subnet_id = azurerm_subnet.web.id 109 | public_ip_address_id = azurerm_public_ip.pip.id 110 | private_ip_address_allocation = var.allocation_method[1] 111 | } 112 | } 113 | 114 | 115 | # 116 | # - Create a Linux Virtual Machine 117 | # 118 | 119 | resource "azurerm_linux_virtual_machine" "vm" { 120 | name = "${var.prefix}-linuxvm" 121 | resource_group_name = azurerm_resource_group.rg.name 122 | location = azurerm_resource_group.rg.location 123 | network_interface_ids = [azurerm_network_interface.nic.id] 124 | size = var.virtual_machine_size 125 | computer_name = var.computer_name 126 | admin_username = var.admin_username 127 | admin_password = var.admin_password 128 | disable_password_authentication = false 129 | 130 | os_disk { 131 | name = "${var.prefix}-${var.os_disk.name}" 132 | caching = var.os_disk.caching 133 | storage_account_type = var.os_disk.storage_account_type 134 | disk_size_gb = var.os_disk.size 135 | } 136 | 137 | source_image_reference { 138 | publisher = var.os_image.publisher 139 | offer = var.os_image.offer 140 | sku = var.os_image.sku 141 | version = var.os_image.version 142 | } 143 | 144 | provisioner "local-exec" { 145 | command = "echo 'Hello, This is the output of Local-Exec Provisioner'" 146 | } 147 | 148 | provisioner "remote-exec" { 149 | inline = [ 150 | "echo 'Hello, This is the output of Remote-Exec Provisioner'" 151 | ] 152 | connection { 153 | type = "ssh" 154 | user = var.admin_username 155 | password = var.admin_password 156 | host = azurerm_public_ip.pip.ip_address 157 | } 158 | } 159 | 160 | tags = var.tags 161 | 162 | } 163 | 164 | -------------------------------------------------------------------------------- /intermediate/azure/Terraform-Provisioners/variables.tf: -------------------------------------------------------------------------------- 1 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 2 | # Linux VM - Variables 3 | #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* 4 | 5 | # Service Principal Variables 6 | 7 | variable "client_id" { 8 | description = "Client ID (APP ID) of the application" 9 | type = string 10 | } 11 | 12 | variable "client_secret" { 13 | description = "Client Secret (Password) of the application" 14 | type = string 15 | } 16 | 17 | variable "subscription_id" { 18 | description = "Subscription ID" 19 | type = string 20 | } 21 | 22 | variable "tenant_id" { 23 | description = "Tenant ID" 24 | type = string 25 | } 26 | 27 | # Prefix and Tags 28 | 29 | variable "prefix" { 30 | description = "Prefix to append to all resource names" 31 | type = string 32 | default = "Collabnix" 33 | } 34 | 35 | variable "tags" { 36 | description = "Resouce tags" 37 | type = map(string) 38 | default = { 39 | "author" = "Vamsi" 40 | "deployed_with" = "Terraform" 41 | } 42 | } 43 | 44 | # Resource Group 45 | 46 | variable "location" { 47 | description = "Location of the resource group" 48 | type = string 49 | default = "East US" 50 | } 51 | 52 | # Vnet and Subnet 53 | 54 | variable "vnet_address_range" { 55 | description = "IP Range of the virtual network" 56 | type = string 57 | default = "10.0.0.0/16" 58 | } 59 | 60 | variable "subnet_address_range" { 61 | description = "IP Range of the virtual network" 62 | type = string 63 | default = "10.0.1.0/24" 64 | } 65 | 66 | # Public IP and NIC Allocation Method 67 | 68 | variable "allocation_method" { 69 | description = "Allocation method for Public IP Address and NIC Private ip address" 70 | type = list(string) 71 | default = ["Static", "Dynamic"] 72 | } 73 | 74 | 75 | # VM 76 | 77 | variable "virtual_machine_size" { 78 | description = "Size of the VM" 79 | type = string 80 | default = "Standard_B1s" 81 | } 82 | 83 | variable "computer_name" { 84 | description = "Computer name" 85 | type = string 86 | default = "Linuxvm" 87 | } 88 | 89 | variable "admin_username" { 90 | description = "Username to login to the VM" 91 | type = string 92 | default = "linuxadmin" 93 | } 94 | 95 | variable "admin_password" { 96 | description = "Password to login to the VM" 97 | type = string 98 | default = "P@$$w0rD2020*" 99 | } 100 | 101 | variable "os_disk" { 102 | description = "Os Disk Details" 103 | type = object({ 104 | name = string 105 | caching = string 106 | storage_account_type = string 107 | size = number 108 | }) 109 | 110 | default = { 111 | name = "linuxvm-disk" 112 | caching = "ReadWrite" 113 | storage_account_type = "StandardSSD_LRS" 114 | size = 64 115 | } 116 | } 117 | 118 | 119 | variable "os_image" { 120 | description = "OS image details" 121 | type = object({ 122 | publisher = string 123 | offer = string 124 | sku = string 125 | version = string}) 126 | 127 | default = { 128 | publisher = "Canonical" 129 | offer = "UbuntuServer" 130 | sku = "16.04-LTS" 131 | version = "latest" 132 | } 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /jekyll-theme-hacker.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Gem::Specification.new do |s| 4 | s.name = 'jekyll-theme-hacker' 5 | s.version = '0.1.1' 6 | s.license = 'CC0-1.0' 7 | s.authors = ['Ajeet Raina', 'GitHub, Inc.'] 8 | s.email = ['ajeetraina@gmail.com'] 9 | s.homepage = 'https://collabnix.github.io/terraform/' 10 | s.summary = 'DockerLabs' 11 | 12 | s.files = `git ls-files -z`.split("\x0").select do |f| 13 | f.match(%r{^((_includes|_layouts|_sass|assets)/|(LICENSE|README)((\.(txt|md|markdown)|$)))}i) 14 | end 15 | 16 | s.platform = Gem::Platform::RUBY 17 | s.add_runtime_dependency 'jekyll', '> 3.5', '< 5.0' 18 | s.add_runtime_dependency 'jekyll-seo-tag', '~> 2.0' 19 | s.add_development_dependency 'html-proofer', '~> 3.0' 20 | s.add_development_dependency 'rubocop', '~> 0.50' 21 | s.add_development_dependency 'w3c_validators', '~> 1.3' 22 | end 23 | --------------------------------------------------------------------------------