└── 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 |
--------------------------------------------------------------------------------