└── README.md /README.md: -------------------------------------------------------------------------------- 1 | ## Automating Infrastructure on Google Cloud with Terraform: Challenge Lab (GSP345) ## 2 | 3 | **Setup : Create the configuration files**
4 | Make the empty files and directories in _Cloud Shell_ or the _Cloud Shell Editor_. 5 | 6 | ``` 7 | touch main.tf 8 | touch variables.tf 9 | mkdir modules 10 | cd modules 11 | mkdir instances 12 | cd instances 13 | touch instances.tf 14 | touch outputs.tf 15 | touch variables.tf 16 | cd .. 17 | mkdir storage 18 | cd storage 19 | touch storage.tf 20 | touch outputs.tf 21 | touch variables.tf 22 | cd 23 | ``` 24 | 25 | Add the following to the each _variables.tf_ file, and fill in the _GCP Project ID_: 26 | ``` 27 | variable "region" { 28 | default = "us-central1" 29 | } 30 | 31 | variable "zone" { 32 | default = "us-central1-a" 33 | } 34 | 35 | variable "project_id" { 36 | default = "" 37 | } 38 | ``` 39 | Add the following to the _main.tf_ file: 40 | ``` 41 | terraform { 42 | required_providers { 43 | google = { 44 | source = "hashicorp/google" 45 | version = "3.55.0" 46 | } 47 | } 48 | } 49 | 50 | provider "google" { 51 | project = var.project_id 52 | region = var.region 53 | zone = var.zone 54 | } 55 | 56 | 57 | module "instances" { 58 | source = "./modules/instances" 59 | } 60 | ``` 61 | Run "_terraform init_" in Cloud Shell in the root directory to initialize terraform. 62 | ``` 63 | terraform init 64 | ``` 65 |
**TASK 1: Import infrastructure**
66 | Navigate to _Compute Engine > VM Instances_. Click on _tf-instance-1_. Copy the _Instance ID_ down somewhere to use later.
67 | Navigate to _Compute Engine > VM Instances_. Click on _tf-instance-2_. Copy the _Instance ID_ down somewhere to use later.
68 | Next, navigate to _modules/instances/instances.tf_. Copy the following configuration into the file: 69 | ``` 70 | resource "google_compute_instance" "tf-instance-1" { 71 | name = "tf-instance-1" 72 | machine_type = "n1-standard-1" 73 | 74 | boot_disk { 75 | initialize_params { 76 | image = "debian-cloud/debian-10" 77 | } 78 | } 79 | 80 | network_interface { 81 | network = "default" 82 | } 83 | 84 | metadata_startup_script = <<-EOT 85 | #!/bin/bash 86 | EOT 87 | 88 | allow_stopping_for_update = true 89 | } 90 | 91 | resource "google_compute_instance" "tf-instance-2" { 92 | name = "tf-instance-2" 93 | machine_type = "n1-standard-1" 94 | 95 | boot_disk { 96 | initialize_params { 97 | image = "debian-cloud/debian-10" 98 | } 99 | } 100 | 101 | network_interface { 102 | network = "default" 103 | } 104 | 105 | metadata_startup_script = <<-EOT 106 | #!/bin/bash 107 | EOT 108 | 109 | allow_stopping_for_update = true 110 | } 111 | ``` 112 | To import the first instance, use the following command, using the Instance ID for _tf-instance-1_ you copied down earlier. 113 | ``` 114 | terraform import module.instances.google_compute_instance.tf-instance-1 115 | ``` 116 | To import the second instance, use the following command, using the Instance ID for _tf-instance-2_ you copied down earlier. 117 | ``` 118 | terraform import module.instances.google_compute_instance.tf-instance-2 119 | ``` 120 | The two instances have now been imported into your terraform configuration. You can now run the commands to update the state of Terraform. Type _yes_ at the dialogue after you run the apply command to accept the state changes. 121 | ``` 122 | terraform plan 123 | terraform apply 124 | ``` 125 |
**TASK 2: Configure a remote backend**
126 | Add the following code to the _modules/storage/storage.tf_ file, and fill in the _Bucket Name_: 127 | ``` 128 | resource "google_storage_bucket" "storage-bucket" { 129 | name = "" 130 | location = "US" 131 | force_destroy = true 132 | uniform_bucket_level_access = true 133 | } 134 | ``` 135 | Next, add the following to the _main.tf_ file: 136 | ``` 137 | module "storage" { 138 | source = "./modules/storage" 139 | } 140 | ``` 141 | Run the following commands to initialize the module and create the storage bucket resource. Type _yes_ at the dialogue after you run the apply command to accept the state changes. 142 | ``` 143 | terraform init 144 | terraform apply 145 | ``` 146 | Next, update the _main.tf_ file so that the terraform block looks like the following. Fill in your _GCP Project ID_ for the bucket argument definition. 147 | ``` 148 | terraform { 149 | backend "gcs" { 150 | bucket = "" 151 | prefix = "terraform/state" 152 | } 153 | required_providers { 154 | google = { 155 | source = "hashicorp/google" 156 | version = "3.55.0" 157 | } 158 | } 159 | } 160 | ``` 161 | Run the following to initialize the remote backend. Type _yes_ at the prompt. 162 | ``` 163 | terraform init 164 | ``` 165 |
**TASK 3: Modify and update infrastructure**
166 | Navigate to _modules/instances/instance.tf_. Replace the entire contents of the file with the following, and fill in your _Instance 3 ID_: 167 | ``` 168 | resource "google_compute_instance" "tf-instance-1" { 169 | name = "tf-instance-1" 170 | machine_type = "n1-standard-2" 171 | zone = "us-central1-a" 172 | allow_stopping_for_update = true 173 | 174 | boot_disk { 175 | initialize_params { 176 | image = "debian-cloud/debian-10" 177 | } 178 | } 179 | 180 | network_interface { 181 | network = "default" 182 | } 183 | } 184 | 185 | resource "google_compute_instance" "tf-instance-2" { 186 | name = "tf-instance-2" 187 | machine_type = "n1-standard-2" 188 | zone = "us-central1-a" 189 | allow_stopping_for_update = true 190 | 191 | boot_disk { 192 | initialize_params { 193 | image = "debian-cloud/debian-10" 194 | } 195 | } 196 | 197 | network_interface { 198 | network = "default" 199 | } 200 | } 201 | 202 | resource "google_compute_instance" "" { 203 | name = "" 204 | machine_type = "n1-standard-2" 205 | zone = "us-central1-a" 206 | allow_stopping_for_update = true 207 | 208 | boot_disk { 209 | initialize_params { 210 | image = "debian-cloud/debian-10" 211 | } 212 | } 213 | 214 | network_interface { 215 | network = "default" 216 | } 217 | } 218 | ``` 219 | Run the following commands to initialize the module and create/update the instance resources. Type _yes_ at the dialogue after you run the apply command to accept the state changes. 220 | ``` 221 | terraform init 222 | terraform apply 223 | ``` 224 |
**TASK 4: Taint and destroy resources**
225 | Taint the _tf-instance-3_ resource by running the following command, and fill in your _Instance 3 ID_: 226 | ``` 227 | terraform taint module.instances.google_compute_instance. 228 | ``` 229 | Run the following commands to apply the changes: 230 | ``` 231 | terraform init 232 | terraform apply 233 | ``` 234 | Remove the _tf-instance-3_ resource from the _instances.tf_ file. Delete the following code chunk from the file. 235 | ``` 236 | resource "google_compute_instance" "" { 237 | name = "" 238 | machine_type = "n1-standard-2" 239 | zone = "us-central1-a" 240 | allow_stopping_for_update = true 241 | 242 | boot_disk { 243 | initialize_params { 244 | image = "debian-cloud/debian-10" 245 | } 246 | } 247 | 248 | network_interface { 249 | network = "default" 250 | } 251 | } 252 | ``` 253 | Run the following commands to apply the changes. Type _yes_ at the prompt. 254 | ``` 255 | terraform apply 256 | ``` 257 |
**TASK 5: Use a module from the Registry**
258 | Copy and paste the following to the end of _main.tf_ file, fill in _Version Number_ and _Network Name_ instructed in the challenge: 259 | ``` 260 | module "vpc" { 261 | source = "terraform-google-modules/network/google" 262 | version = "~> " 263 | 264 | project_id = "qwiklabs-gcp-04-f2c1c01a09d3" 265 | network_name = "" 266 | routing_mode = "GLOBAL" 267 | 268 | subnets = [ 269 | { 270 | subnet_name = "subnet-01" 271 | subnet_ip = "10.10.10.0/24" 272 | subnet_region = "us-central1" 273 | }, 274 | { 275 | subnet_name = "subnet-02" 276 | subnet_ip = "10.10.20.0/24" 277 | subnet_region = "us-central1" 278 | subnet_private_access = "true" 279 | subnet_flow_logs = "true" 280 | description = "This subnet has a description" 281 | } 282 | ] 283 | } 284 | ``` 285 | Run the following commands to initialize the module and create the VPC. Type _yes_ at the prompt. 286 | ``` 287 | terraform init 288 | terraform apply 289 | ``` 290 | Navigate to _modules/instances/instances.tf_. Replace the entire contents of the file with the following: 291 | ``` 292 | resource "google_compute_instance" "tf-instance-1" { 293 | name = "tf-instance-1" 294 | machine_type = "n1-standard-2" 295 | zone = "us-central1-a" 296 | allow_stopping_for_update = true 297 | 298 | boot_disk { 299 | initialize_params { 300 | image = "debian-cloud/debian-10" 301 | } 302 | } 303 | 304 | network_interface { 305 | network = "" 306 | subnetwork = "subnet-01" 307 | } 308 | } 309 | 310 | resource "google_compute_instance" "tf-instance-2" { 311 | name = "tf-instance-2" 312 | machine_type = "n1-standard-2" 313 | zone = "us-central1-a" 314 | allow_stopping_for_update = true 315 | 316 | boot_disk { 317 | initialize_params { 318 | image = "debian-cloud/debian-10" 319 | } 320 | } 321 | 322 | network_interface { 323 | network = "" 324 | subnetwork = "subnet-02" 325 | } 326 | } 327 | ``` 328 | Run the following commands to initialize the module and update the instances. Type _yes_ at the prompt. 329 | ``` 330 | terraform init 331 | terraform apply 332 | ``` 333 |
**TASK 6: Configure a firewall**
334 | Add the following resource to the _main.tf_ file, fill in the _GCP Project ID_ and _Network Name_: 335 | ``` 336 | resource "google_compute_firewall" "tf-firewall" { 337 | name = "tf-firewall" 338 | network = "projects//global/networks/" 339 | 340 | allow { 341 | protocol = "tcp" 342 | ports = ["80"] 343 | } 344 | 345 | source_tags = ["web"] 346 | source_ranges = ["0.0.0.0/0"] 347 | } 348 | ``` 349 | Run the following commands to configure the firewall. Type _yes_ at the prompt. 350 | ``` 351 | terraform init 352 | terraform apply 353 | ``` 354 | --------------------------------------------------------------------------------