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 | 
27 |
28 | - If you want to see the error page, append /error to the url.
29 |
30 |
31 |
32 | 
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 | 
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 | 
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 | 
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 |
--------------------------------------------------------------------------------