├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── img ├── .DS_Store ├── 000-IAP-gce-demo-main godemos.png ├── 000-IAP-gce-demo-main.png ├── 010-Google-SDK-sign-in.png ├── 011-Google-SDK-password.png ├── 012-Google-SDK-access.png ├── 020-AuthAppDef-sign-in.png ├── 021-AuthAppDef-access.png ├── 030-test-web.png ├── 040-test-ssh.png ├── 041-show-gcloud.png ├── 042-ssh-login.png ├── 070-vm-line.png ├── 071-instance-info.png ├── 072-instance-group.png ├── 073-backend-service.png ├── 075-url-map.png ├── 076-ssl-policy.png ├── 077-ssl-cert.png ├── 080-iap-https.png └── 081-iap-ssh.png └── modules ├── 00-global-variables ├── .gitignore └── outputs.tf.example ├── 10-enable-apis ├── main.tf ├── output.tf └── providers.tf ├── 20-create-iap-brand ├── main.tf ├── outputs.tf └── providers.tf └── 90-build-demo ├── main.tf ├── outputs.tf └── providers.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac specific items 2 | .DS_Store 3 | 4 | # Local .terraform directories 5 | **/.terraform/* 6 | 7 | # .tfstate files 8 | *.tfstate 9 | *.tfstate.* 10 | 11 | # Terraform generated lock files 12 | .terraform.lock.hcl 13 | 14 | # Crash log files 15 | crash.log 16 | 17 | # Vi editor swap files 18 | *.swp 19 | 20 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 21 | # .tfvars files are managed as part of configuration and so should be included in 22 | # version control. 23 | # 24 | # example.tfvars 25 | 26 | # Ignore override files as they are usually used to override resources locally and so 27 | # are not checked in 28 | override.tf 29 | override.tf.json 30 | *_override.tf 31 | *_override.tf.json 32 | 33 | # Include override files you do wish to add to version control using negated pattern 34 | # 35 | # !example_override.tf 36 | 37 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 38 | # example: *tfplan* 39 | plan.out 40 | 41 | terraform.tfvars 42 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code Reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google/conduct/). 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Using Google Cloud Identity-Aware Proxy with Compute Engine 2 | 3 | ## Introduction 4 | 5 | Google Cloud's [Identity-Aware Proxy](https://cloud.google.com/iap) ("IAP") service enables you to control access to your cloud-based and on-premises applications. You can use IAP to protect web resources such as Google Compute Engine ("GCE") instances running web applications and Google App Engine ("GAE"). Users browsing protected resources must authenticate to gain access. You can also use [IAP TCP forwarding](https://cloud.google.com/iap/docs/using-tcp-forwarding) to protect TCP resources such as SSH. 6 | Users attempting to open TCP sessions must also first authenticate before being granted access. You can use both of these capabilities together. For example, you may want to restrict access to a web application and also limit SSH access to the web server. 7 | 8 | In this demonstration, you will learn how IAP works with both the web and TCP flows. You will build an environment by running a series of Terraform deployments. 9 | After you build the environment, you will test both the web and TCP flows. You will then examine the configurations of the resources using the Google Cloud console to get a better understanding of how to configure IAP. 10 | 11 | ## Architecture overview 12 | 13 | Here's a diagram of what you will build. 14 | 15 | ![Google Compute Engine Architectural Overview](./img/000-IAP-gce-demo-main.png) 16 |

Figure 1 - Identity-Aware Proxy demo architecture

17 | 18 | Figure 1 shows a web environment with an HTTPS Global Load Balancer frontend and an unmanaged instance group with a Compute Engine instance as the backend.. 19 | The instance runs the Ubuntu operating system and uses Apache to provide web services. 20 | The instance uses [Cloud NAT](https://cloud.google.com/nat/docs/overview) for outbound internet access in order to download packages and updates. 21 | The instance has no external IP address to support access from the internet. 22 | All inbound access, both for web (HTTPS) and ssh (TCP) will be provided by IAP. 23 | 24 | The left section of Figure 1 shows the IAP TCP flow. A user wanting to SSH into the back end instance clicks the SSH but on the Compute Engine console or uses "gcloud compute ssh --tunnel-through-iap" to begin the session. 25 | IAP then prompts the user for an identity. 26 | If the identity has the "IAP-secured Tunnel User" role, an encrypted tunnel is created between the console or the gcloud client to the Google endpoint tunnel.cloudproxy.app. After the tunnel is created, SSH then begins an encrypted session through the encrypted tunnel to the instance providing two layers of encryption. 27 | 28 | The right portion of Figure 1 shows the HTTPS flow. 29 | A user browses to a URL secured with an SSL/TLS certificate that points to the IP address of a forwarding rule on the HTTPS Global Load Balancer. 30 | The forwarding rule points to a backend protected by IAP. 31 | IAP prompts the user for an identity. 32 | If the identity has the "IAP-secured Web App User" role, the session passes to the backend web server. 33 | 34 | ## Prerequisites 35 | 36 | 1. You will the project ID of a new Google Cloud project linked to a billing account. You should use a new project to avoid interfering with other workloads. IAP branding, which is used in this demonstration, can only be deleted by deleting the GCP project. 37 | 38 | 2. You will need a workstation with [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) and the [Google Cloud SDK](https://cloud.google.com/sdk/docs/install). Here are the versions used to create this demo: 39 | 40 | - Terraform: v1.1.7 41 | - Google Cloud SDK: 379.0.0 42 | 43 | You can use newer versions of these tools but older versions may not include all of the features used in this demo. Add the terraform and gcloud programs to your command search path. 44 | 45 | 3. You will need a fully qualified DNS hostname and the ability to update its IP address (the "A" record).. 46 | 47 | 4. You will need an SSL certificate and private key associated with the DNS hostname. These files should be accessible from your workstation. The files must be in PEM format. 48 | 49 | 5. You will need a user ID in the Google Cloud project that has accepted the Google Cloud Terms of Service. The user must have the following IAM roles: 50 | 51 | - Compute Admin (for setting up the network, instance, and load balancer) 52 | - IAP Policy Admin (for setting up the Identity Aware Proxy) 53 | - Logging Admin (for managing logs) 54 | - OAuth Config Editor (for updating the OAuth information) 55 | - Service Usage Admin (for allowing Terraform to enable APIs and to use a project for billing and quota purposes) 56 | 57 | User IDs in Google Cloud are in the form of email addresses. 58 | This user ID will also become part of the OAuth and IAP configurations. 59 | The email address must belong to the currently logged in user account. 60 | 61 | 6. There must not be any organization constraints that restrict the ability to deploy the services. You can change these settings in the Google Cloud console under IAM & Admin > Organization Policies at the project level. Examples of such constraints include (but are not limited to): 62 | 63 | - The policy "Restrict Load Balancer Creation Based on Load Balancer Types" must allow the EXTERNAL_HTTP_HTTPS load balancer (the classic Global Load Balancer) type. 64 | 65 | 7. You should be familiar with using the Google Cloud console and Terraform. 66 | 67 | 8. There are minor charges for the resources used, such as an e2.micro Compute Engine instance. To avoid future charges, follow the cleanup instructions. 68 | 69 | 70 | ## Build instructions 71 | 72 | ### Configure authentication 73 | 74 | 1. Launch a terminal session. 75 | 76 | 2. Sign on to your Google Cloud account as the user for the Google Cloud project using the command below. 77 | 78 | ``` 79 | gcloud auth login 80 | ``` 81 | 82 | In addition to the user ID and password, you may also be asked to grant access to the Google Cloud SDK. See Figure 2 for more details. 83 | 84 | 85 | | Enter user | Enter password | Grant access | 86 | | :-: | :-: | :-: | 87 | | ![SDK sign in user](./img/010-Google-SDK-sign-in.png) | ![SDK sign in password](./img/011-Google-SDK-password.png) | ![SDK access](./img/012-Google-SDK-access.png) | 88 | 89 |

Figure 2 - Google SDK sign in process

90 | 91 | 92 | 2. Set your default project ID using the command below, using your project ID in place of *INSERT-PROJECT-ID-HERE*. 93 | 94 | ``` 95 | gcloud config set project *INSERT-PROJECT-ID-HERE* 96 | ``` 97 | 98 | 3. Set your application default credentials so Terraform has credentials to run. 99 | 100 | ``` 101 | gcloud auth application-default login 102 | ``` 103 | You may be prompted for a user ID and password and also to grant access to the Google Auth Library as shown in Figure 3. 104 | | Enter user | Grant access | 105 | | :-: | :-: | 106 | | ![AuthApp sign in user](./img/020-AuthAppDef-sign-in.png) | ![AuthApp access](./img/021-AuthAppDef-access.png) | 107 | 108 | ### Download the demo repository 109 | 110 | 1. Clone this repository to your workstation. 111 | 112 | ``` 113 | git clone https://github.com/google/iap-compute-engine-demo.git 114 | ``` 115 | 116 | 2. Change your working directory to the newly-cloned repository. 117 | 118 | ``` 119 | cd iap-compute-engine-demo 120 | ``` 121 | 122 | 3. Set the environment variable to the current directory for easy navigation. 123 | 124 | ``` 125 | export DEMOHOME=`pwd` 126 | ``` 127 | 128 | 4. Here's a diagram of the repository. 129 | 130 | ``` 131 | . 132 | ├── LICENSE 133 | ├── README.md 134 | ├── img 135 | │   └── 000-IAP-gce-demo-main.png 136 | └── modules 137 | ├── 00-global-variables 138 | │   └── outputs.tf.example 139 | ├── 10-enable-apis 140 | │   ├── main.tf 141 | │   └── providers.tf 142 | ├── 20-create-iap-brand 143 | │   ├── main.tf 144 | │   └── providers.tf 145 | └── 90-build-demo 146 | ├── main.tf 147 | ├── outputs.tf 148 | └── providers.tf 149 | ``` 150 | 151 |
Figure 3 - Demo directory structure
152 | 153 | All Terraform modules are in the *modules* directory. Each module will have its own local Terraform state. Here's a description of each module. 154 | 155 | - 00-global-variables 156 | 157 | All global variables for the demo are defined here and presented as outputs that are referenced in the other modules 158 | 159 | - 10-enable-apis 160 | 161 | This module enables all of the Google Cloud APIs that are needed for the demo. Destroying the module clears the state information but does not disable the APIs. 162 | 163 | - 20-create-iap-brand 164 | 165 | This module defines the OAuth brand for IAP. Only one brand is allowed per Google Cloud project. The brand cannot be deleted after it is defined. Destroying the module clears the state information but does not delete the brand. 166 | 167 | - 90-build-demo 168 | 169 | This module builds the demo. The module outputs the IP address of the load balancer frontend forwarding rule. Destroying this module will free up all Google Cloud resources. 170 | 171 | ### Deploy the demo 172 | 173 | #### Define the global variables 174 | 175 | 1. Change to the 00-global-variables directory. 176 | 177 | ``` 178 | cd $DEMOHOME/modules/00-global-variables 179 | ``` 180 | 181 | 2. Create the file outputs.tf from the outputs.tf.example file. 182 | 183 | ``` 184 | cp outputs.tf.example outputs.tf 185 | ``` 186 | 187 | 3. Using the text editor of your choice, open outputs.tf. The first part of the file contains required value as shown in Figure 4. as described below, Do not delete the quotation marks. 188 | 189 | ``` 190 | # Begin - Required Values 191 | 192 | output "project_id" { 193 | value = "INSERT-PROJECT-ID-HERE" 194 | } 195 | 196 | output "ssl_certificate_file" { 197 | value = "/path/to/certificate" 198 | } 199 | 200 | output "ssl_private_key_file" { 201 | value = "/path/to/privatekey" 202 | } 203 | 204 | output "iap_test_user" { 205 | value = "testuser@example.com" 206 | } 207 | 208 | # End - Required Values 209 | ``` 210 | 211 |
Figure 4 - Demo directory structure
212 | 213 | 4. Edit outputs.tf as described below. 214 | 215 | - Replace *INSERT-PROJECT-ID-HERE* with your Google Cloud project id. 216 | 217 | - Replace */path/to/certificate* with the path to the certificate file in PEM format. You can use either an absolute or relative path. The name of the certificate file will vary based on the issuer. Common names of this file are cert.pem or certificate.crt. 218 | 219 | - Replace */path/to/privatekey* with the path to the private key file in PEM format. You can use either an absolute or relative path. The name of the private key file will vary based on the issuer. Common names of this file are privkey.pem or private.key. 220 | 221 | - Replace *testuser@example.com* with your user ID (in email format). This will be used for both the OAuth consent screen and for granting access to SSH and to the web page. 222 | 223 | - (Optional) edit the remaining value to change the region, zone, image project, and image family. Note: This demo has only been tested for the Ubuntu 20.04 LTS operating system! 224 | 225 | 5. Save the outputs.tf file and exit the text editor. 226 | 227 | 6. Use the commands below to build this Terraform module. 228 | 229 | ``` 230 | terraform init 231 | terraform plan --out=plan.out 232 | terraform apply plan.out 233 | ``` 234 | 235 | You should see the message "Apply Complete" followed by output values corresponding to the edits in the file. If any error messages appear, edit the outputs.tf to fix the errors and repeat the three terraform commands above. 236 | 237 | #### Enable the Google Cloud APIs 238 | 239 | The demo uses several Google Cloud APIs. The module named *10-enable-apis* enables these APIs for use in the Google Cloud project. Note that Running *terraform destroy* in this module does not disable the APIs. 240 | 241 | 1. cd $DEMOHOME/modules/10-enable-apis 242 | 243 | 2. Use the commands below to build this Terraform module. 244 | 245 | ``` 246 | terraform init 247 | terraform plan --out=plan.out 248 | terraform apply plan.out 249 | ``` 250 | 251 | 3. Upon successful completion, you will see "Apply Complete" followed by a lost of APIs that were enabled. 252 | 253 | #### Deploy the OAuth IAP brand 254 | 255 | In order to enable IAP, the demo sets up the [OAuth consent screen](https://cloud.google.com/iap/docs/programmatic-oauth-clients). The consent screen contains branding information. 256 | 257 | > **NOTE:** You can only run this module once within a Google Cloud project as Google Cloud only allows one brand per project and it is not possible to delete the OAuth brand information. If you need to rebuild the demo in the same project, skip this section and proceed to the *Deploy the demo" section below. 258 | 259 | 1. Change your working directory to the 20-create-iap-brand module. 260 | 261 | ``` 262 | cd $DEMOHOME/modules/20-create-iap-brand 263 | ``` 264 | 265 | 2. Use the commands below to build this Terraform module. 266 | 267 | ``` 268 | terraform init 269 | terraform plan --out=plan.out 270 | terraform apply plan.out 271 | ``` 272 | 273 | #### Deploy the demo 274 | 275 | 1. Change your working directory to the 90-build-demo module. 276 | 277 | ``` 278 | cd $DEMOHOME/modules/90-build-demo 279 | ``` 280 | 281 | 2. Use the commands below to build this Terraform module. 282 | 283 | ``` 284 | terraform init 285 | terraform plan --out=plan.out 286 | terraform apply plan.out 287 | ``` 288 | 289 | 3. Upon successful completion, you will see "Apply Complete" followed by the IP address of the HTTPS Global Load Balancer. 290 | 291 | #### Configure DNS 292 | 293 | In order to launch to display the web server home page, you must make a DNS change. 294 | 295 | 1. Follow the instructions of your DNS provider, create or modify the address record (the "A" record) for the host name to point to the IP address for the load balancer as provided by the previous step. The host name must be associated with the SSL certificate you supplied. You should use a low time-to-live ("TTL") to make it easier to change the IP address if you rebuild the demo at a later time. 296 | 297 | 2. Wait for the DNS change to propagate. 298 | 299 | ### Test the demo 300 | 301 | 1. To test the web flow, open an incognito/private tab in your browser and browse to the DNS host name that is associated with the SSL certificate and IP address. 302 | 303 | 2. You will be prompted by the Identity-Aware Proxy to authenticate. 304 | 305 | 3. Upon successful authentication, you will see the web server home page with the web server's instance name, internal IP address, and instance ID as shown in Figure 5. 306 | 307 | ![Test of web flow](./img/030-test-web.png) 308 |

Figure 5 - Test of web IAP flow

309 | 310 | 4. To test the SSH flow, on the Google Cloud console, go to the Compute Engine->VM Instances menu. Look at the line containing the demo-web-server instance. Notice that there is no external IP address for the instance. 311 | 312 | To the right of the demo-web-server instance, click the down arrow next to SSH and then click the *View gcloud command* option as shown in Figure 6. 313 | 314 | ![Display the ssh options](./img/040-test-ssh.png) 315 |

Figure 6 - Display options for ssh IAP flow

316 | 317 | 5. You will see The gcloud command as shown in Figure 7. 318 | 319 | ![ssh gcloud command](./img/041-show-gcloud.png) 320 |

Figure 7 - gcloud command for accessing the instance

321 | 322 | The *gcloud compute ssh* command selects the instance by name, zone, and project. The command also includes a *--tunnel-through-iap* argument to cause the connection to the instance to be brokered by IAP. 323 | 324 | 6. Click the *copy-to-clipboard* icon next to the gcloud command and then bring up the Cloud Shell and paste the gcloud command into the Cloud Shell window and press *enter*. 325 | 326 | 7. You will be asked to provide authentication information. You may be asked to choose a passphrase. If so, make a note of your passphrase in case you need it later. You will then be taken to an ssh session on the web server instance as shown in Figure 8. 327 | 328 | ![ssh gcloud command](./img/042-ssh-login.png) 329 |

Figure 8 - SSH session on web server

330 | 331 | You have successfully completed the testing of the web and SSH flows through the Identity-Aware Proxy. In both flows, you were asked to authenticate to establish your identity. After authenticating, you were granted access to the web page and ssh session. 332 | 333 | ### Behind the scenes 334 | 335 | Now that you have built and tested the demo environment, you will now explore some of the underlying services to see how they are configured. You will first examine the configuration of the load balancer backend and work your way up through the load balancer configuration. You will then examine the configuration of IAP. 336 | 337 | 1. In the Google Cloud console, select Compute Engine -> VM Instances. You will see an instance named *demo-web-server* as shown in Figure 9. 338 | 339 | ![VM with no IP address](./img/070-vm-line.png) 340 |

Figure 9 - Web server instance

341 | 342 | The instance has no external IP address and can therefore not be accessed directly from the internet. The IAP will broker the external access attempts and provide connections to the instances's internal IP address. 343 | 344 | 2. Click on the name of the instance (*demo-web-server*). You will see information about the instance as shown in Figure 10. 345 | 346 | ![web server instance information](./img/071-instance-info.png) 347 |

Figure 10 - Web server instance information

348 | 349 | You can see the instance ID that was displayed on the server home page. Also, the instance belongs to an instance group named *demo-web-server-group*. 350 | 351 | 3. Click on the instance group name *demo-web-server-group*. The instance group appears as shown in Figure 11. 352 | 353 | ![instance group information](./img/072-instance-group.png) 354 |

Figure 11 - Instance group information

355 | 356 | The instance group is unmanaged and contains only the single web server instance. The instance group is part of the load balancer backend service named **demo-web-server-backend-service*. 357 | 358 | 4. Click on *demo-web-server-backend-service*. The backend service appears as shown in Figure 12. 359 | 360 | ![backend service information](./img/073-backend-service.png) 361 |

Figure 12 - Backend service information

362 | 363 | 5. Click on *demo-load-balancer-url-map*. Figure 13 shows the load balancer URL map which defines the top level of the load balancer configuration. 364 | 365 | ![load balancer URL map](./img/075-url-map.png) 366 |

Figure 13 - Load balancer URL map

367 | 368 | 6. Open the *demo-ssl-policy* link in a new browser tab. In Figure 14, you can see the SSL policy has been set to MODERN which limits the ciphers that are accepted and that a minimum of TLS 1.2 is required. 369 | 370 | ![SSL Policy](./img/076-ssl-policy.png) 371 |

Figure 14 - Load balancer SSL policy

372 | 373 | 7. Go to the browser tab with the URL map and open *demo-certificate* in a new browser tab. In Figure 15, you can see the properties of the certificate that you provided. 374 | 375 | ![SSL Policy](./img/077-ssl-cert.png) 376 |

Figure 15 - Load balancer SSL certificate

377 | 378 | 379 | You have now seen how the load balancer backend service is configured with an instance group that contains a single instance. You will now look at the configuration of IAP. 380 | 381 | 8. In the Google Cloud Console menu click Security > Identity-Aware Proxy. 382 | 383 | 9. As shown in figure 16, do the following: 384 | 385 | - Click *HTTPS RESOURCES* 386 | - Check the box next to *demo-web-server-backend-service* 387 | - Open the toggle next to *IAP-secured Web App User* 388 | 389 | ![IAP HTTPS configuration](./img/080-iap-https.png) 390 |

Figure 16 - IAP HTTPS configuration

391 | 392 | The line that contains *demo-web-server-backend-service* refers to the backend service that you had seen in a previous step. The slider is to the right which means that IAP is enabled on that backend service. Under IAP-secured Web App user, you can see that the name of the test user. The test user is allowed to access the backend service (which ultimately points to the web server) after successfully authenticating. 393 | 394 | 10. As shown in figure 17, do the following: 395 | 396 | - Click *SSH AND TCP RESOURCES* 397 | - Check the box next to *demo-web-server* 398 | - Open the toggle next to *IAP-secured Tunnel User* 399 | 400 | 401 | ![IAP SSH configuration](./img/081-iap-ssh.png) 402 |

Figure 17 - IAP SSH configuration

403 | 404 | The line that contains *demo-web-server* refers to the web-server-instance. The slider is to the right which means that IAP is enabled on that instance. Under IAP-secured Tunnel User, you can see that the name of the test user. The test user is allowed to ssh to the web server after successfully authenticating. 405 | 406 | You will also see a warning next to demo-web-server. The reason for this warning is that the firewall rule in the VPC network only allows TCP port 22 for SSH. You can use IAP TCP forwarding to proxy access to any TCP port. The warning is saying that you may want to open additional ports on the firewall. Since the firewall rule only needs to allow port 22 for SSH tunneling, you can safely ignore the warning. 407 | 408 | You have now seen how IAP is configure for both the web and TCP flows. In the next section, you will clean up the demo environment. 409 | 410 | ### Clean up 411 | 412 | Please follow the steps below to remove the demonstration environment. 413 | 414 | 1. Change your working directory to the 90-build-demo module. 415 | 416 | ``` 417 | cd $DEMOHOME/modules/90-build-demo 418 | ``` 419 | 420 | 2. Use the command below to destroy the demo environment. 421 | 422 | ``` 423 | terraform destroy 424 | ``` 425 | 426 | Respond with *yes* when asked to confirm that you want to destroy the resources. 427 | 428 | 3. Upon successful completion, you will see "Destroy complete." You do not have to destroy any of the other modules. 429 | 430 | 4. If you want to delete the IAP OAuth branding information and are *not* using the GCP project for anything else, you can delete the GCP project. 431 | 432 | ## Error messages 433 | 434 | The table below lists errors you may encounter when deploying this demo and remediation steps. 435 | 436 | | Error | Remediation | 437 | |--|--| 438 | | "UREQ_TOS_NOT_ACCEPTED" | This error arises when deploying the demo with a newly-created user ID. You must log into the Google Cloud console with this user ID and accept the Google Cloud Terms of Service. | 439 | -------------------------------------------------------------------------------- /img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/.DS_Store -------------------------------------------------------------------------------- /img/000-IAP-gce-demo-main godemos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/000-IAP-gce-demo-main godemos.png -------------------------------------------------------------------------------- /img/000-IAP-gce-demo-main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/000-IAP-gce-demo-main.png -------------------------------------------------------------------------------- /img/010-Google-SDK-sign-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/010-Google-SDK-sign-in.png -------------------------------------------------------------------------------- /img/011-Google-SDK-password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/011-Google-SDK-password.png -------------------------------------------------------------------------------- /img/012-Google-SDK-access.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/012-Google-SDK-access.png -------------------------------------------------------------------------------- /img/020-AuthAppDef-sign-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/020-AuthAppDef-sign-in.png -------------------------------------------------------------------------------- /img/021-AuthAppDef-access.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/021-AuthAppDef-access.png -------------------------------------------------------------------------------- /img/030-test-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/030-test-web.png -------------------------------------------------------------------------------- /img/040-test-ssh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/040-test-ssh.png -------------------------------------------------------------------------------- /img/041-show-gcloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/041-show-gcloud.png -------------------------------------------------------------------------------- /img/042-ssh-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/042-ssh-login.png -------------------------------------------------------------------------------- /img/070-vm-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/070-vm-line.png -------------------------------------------------------------------------------- /img/071-instance-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/071-instance-info.png -------------------------------------------------------------------------------- /img/072-instance-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/072-instance-group.png -------------------------------------------------------------------------------- /img/073-backend-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/073-backend-service.png -------------------------------------------------------------------------------- /img/075-url-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/075-url-map.png -------------------------------------------------------------------------------- /img/076-ssl-policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/076-ssl-policy.png -------------------------------------------------------------------------------- /img/077-ssl-cert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/077-ssl-cert.png -------------------------------------------------------------------------------- /img/080-iap-https.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/080-iap-https.png -------------------------------------------------------------------------------- /img/081-iap-ssh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/iap-compute-engine-demo/6e290d5a6f5312b2fe456a7a045d3576bec47153/img/081-iap-ssh.png -------------------------------------------------------------------------------- /modules/00-global-variables/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the outputs.tf file in this directory since it is modified to 2 | # define the variables used across modules. 3 | 4 | outputs.tf 5 | -------------------------------------------------------------------------------- /modules/00-global-variables/outputs.tf.example: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Begin - Required Values 16 | 17 | output "project_id" { 18 | value = "INSERT-PROJECT-ID-HERE" 19 | } 20 | 21 | output "ssl_certificate_file" { 22 | value = "/path/to/certificate" 23 | } 24 | 25 | output "ssl_private_key_file" { 26 | value = "/path/to/privatekey" 27 | } 28 | 29 | output "iap_test_user" { 30 | value = "testuser@example.com" 31 | } 32 | 33 | # End - Required Values 34 | 35 | # Begin - Optional Values 36 | 37 | output "machine_type" { 38 | value = "e2-micro" 39 | } 40 | 41 | output "image_project" { 42 | value = "ubuntu-os-cloud" 43 | } 44 | 45 | output "image_family" { 46 | value = "ubuntu-2004-lts" 47 | } 48 | 49 | output "region" { 50 | value = "us-central1" 51 | } 52 | 53 | output "zone" { 54 | value = "us-central1-a" 55 | } 56 | 57 | # End - Optional Value 58 | -------------------------------------------------------------------------------- /modules/10-enable-apis/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | locals { 16 | google_cloud_api_set = toset([ 17 | "compute.googleapis.com", 18 | "iam.googleapis.com", 19 | "iap.googleapis.com" 20 | ]) 21 | } 22 | 23 | module "global_variables" { 24 | source = "../00-global-variables" 25 | } 26 | 27 | resource "google_project_service" "google_cloud_api" { 28 | provider = google 29 | 30 | for_each = local.google_cloud_api_set 31 | 32 | service = each.key 33 | disable_dependent_services = false 34 | disable_on_destroy = false 35 | } 36 | -------------------------------------------------------------------------------- /modules/10-enable-apis/output.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | output "Google_Cloud_Enabled_APIs" { 16 | value = local.google_cloud_api_set 17 | } 18 | -------------------------------------------------------------------------------- /modules/10-enable-apis/providers.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | terraform { 16 | required_providers { 17 | google = { 18 | source = "hashicorp/google" 19 | version = ">= 4.16.0" 20 | } 21 | } 22 | } 23 | 24 | provider "google" { 25 | project = module.global_variables.project_id 26 | region = module.global_variables.region 27 | zone = module.global_variables.zone 28 | } 29 | -------------------------------------------------------------------------------- /modules/20-create-iap-brand/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This module is used to create the IAP OAuth brand for the IAP demo. 16 | # There currently can only be one brand per Google Cloud project. Since 17 | # brands cannot be deleted from projects, building out this Terraform plan 18 | # will fail on subseequent attempts will trigger an error. Moving the brand 19 | # resource to a separate module prevents the build of the 90-build-demo module 20 | # from aborting. 21 | 22 | module "global_variables" { 23 | source = "../00-global-variables" 24 | } 25 | 26 | resource "google_iap_brand" "demo_iap_brand" { 27 | support_email = module.global_variables.iap_test_user 28 | application_title = "IAP Demo" 29 | } 30 | -------------------------------------------------------------------------------- /modules/20-create-iap-brand/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | output "user" { 16 | value = module.global_variables.iap_test_user 17 | } 18 | -------------------------------------------------------------------------------- /modules/20-create-iap-brand/providers.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | terraform { 16 | required_providers { 17 | google = { 18 | source = "hashicorp/google" 19 | version = ">= 4.16.0" 20 | } 21 | } 22 | } 23 | 24 | provider "google" { 25 | project = module.global_variables.project_id 26 | region = module.global_variables.region 27 | zone = module.global_variables.zone 28 | } 29 | -------------------------------------------------------------------------------- /modules/90-build-demo/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Set up global variables, data sources, and local variables 16 | 17 | module "global_variables" { 18 | source = "../00-global-variables" 19 | } 20 | 21 | data "google_compute_image" "web_server_image" { 22 | provider = google 23 | 24 | family = module.global_variables.image_family 25 | project = module.global_variables.image_project 26 | } 27 | 28 | data "google_project" "this_project" { 29 | provider = google 30 | } 31 | 32 | locals { 33 | project_number = data.google_project.this_project.number 34 | } 35 | 36 | # Set up network resources 37 | 38 | resource "google_compute_network" "vpc_network" { 39 | provider = google 40 | 41 | name = "demo-vpc" 42 | description = "VPC for the resources for the IAP demo" 43 | auto_create_subnetworks = false 44 | } 45 | 46 | resource "google_compute_subnetwork" "vpc_subnet" { 47 | provider = google 48 | 49 | name = "demo-subnet" 50 | description = "Subnet for the web servers for the IAP demo VPC" 51 | ip_cidr_range = "10.100.10.0/24" 52 | network = google_compute_network.vpc_network.id 53 | } 54 | 55 | resource "google_compute_firewall" "fw_tunneled_ssh_traffic" { 56 | provider = google 57 | 58 | name = "fw-tunneled-ssh-traffic" 59 | description = "Firewall to allow tunneled SSH traffic" 60 | 61 | network = google_compute_network.vpc_network.name 62 | direction = "INGRESS" 63 | 64 | allow { 65 | protocol = "tcp" 66 | ports = ["22"] 67 | } 68 | 69 | source_ranges = [ "35.235.240.0/20" ] 70 | } 71 | 72 | resource "google_compute_firewall" "fw_healthcheck_and_proxied_traffic" { 73 | provider = google 74 | 75 | name = "fw-healthcheck-and-proxied-traffic" 76 | description = "Firewall rule to allow health checks and proxied traffic" 77 | 78 | network = google_compute_network.vpc_network.name 79 | direction = "INGRESS" 80 | 81 | allow { 82 | protocol = "tcp" 83 | ports = ["80"] 84 | } 85 | 86 | source_ranges = [ "130.211.0.0/22", "35.191.0.0/16" ] 87 | } 88 | 89 | resource "google_compute_router" "vpc_router" { 90 | provider = google 91 | 92 | name = "demo-router" 93 | region = google_compute_subnetwork.vpc_subnet.region 94 | network = google_compute_network.vpc_network.id 95 | } 96 | 97 | resource "google_compute_router_nat" "nat" { 98 | provider = google 99 | 100 | name = "my-router-nat" 101 | router = google_compute_router.vpc_router.name 102 | region = google_compute_router.vpc_router.region 103 | nat_ip_allocate_option = "AUTO_ONLY" 104 | source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" 105 | 106 | log_config { 107 | enable = true 108 | filter = "ERRORS_ONLY" 109 | } 110 | } 111 | 112 | # Set up compute 113 | 114 | # web_server_template - instance template for creating a web server 115 | # 116 | # startup-script - Meta data key to install Apache and a home page 117 | # 118 | # The home page consists of the instance's name and internal IP address. 119 | # 120 | # Notes: 121 | # 122 | # (1) There are nested heredocs below, including the definition of the script 123 | # (delimited by SCRIPT) and the creation of the home page (delimited by 124 | # EOF). 125 | # (2) The SCRIPT heredoc begins with "<<-" to strip off leading spaces. 126 | # If you remove the "-" from "<<-", the heredoc will include the leading 127 | # spaces and will not load properly. 128 | 129 | resource "google_compute_instance_template" "web_server_template" { 130 | provider = google 131 | 132 | name_prefix = "demo-template-" 133 | description = "Instance template for the web servers" 134 | region = module.global_variables.region 135 | machine_type = module.global_variables.machine_type 136 | 137 | network_interface { 138 | subnetwork = google_compute_subnetwork.vpc_subnet.self_link 139 | } 140 | 141 | shielded_instance_config { 142 | enable_secure_boot = true 143 | } 144 | 145 | disk { 146 | boot = true 147 | source_image = data.google_compute_image.web_server_image.self_link 148 | } 149 | 150 | metadata = { 151 | enable_oslogin = "TRUE" 152 | startup-script = <<-SCRIPT 153 | #!/bin/bash 154 | MD_URL="http://metadata.google.internal/computeMetadata/v1/instance" 155 | MD_HEADER="Metadata-Flavor: Google" 156 | # 157 | INSTANCE_ID=$(curl $MD_URL/id -H "$MD_HEADER") 158 | INSTANCE_NAME=$(curl $MD_URL/name -H "$MD_HEADER") 159 | INTERNAL_IP=$(curl $MD_URL//network-interfaces/0/ip -H "$MD_HEADER") 160 | # 161 | apt update 162 | apt -y install apache2 163 | cat < /var/www/html/index.html 164 | 165 | 166 |

Instance name: $INSTANCE_NAME

167 |

Internal IP: $INTERNAL_IP

168 |

Instance ID: $INSTANCE_ID

169 | 170 | 171 | EOF 172 | SCRIPT 173 | } 174 | } 175 | 176 | resource "google_compute_instance_from_template" "web_server" { 177 | provider = google 178 | 179 | name = "demo-web-server" 180 | description = "Web server for unmanaged instanced group for load balancer" 181 | 182 | zone = module.global_variables.zone 183 | source_instance_template = ( 184 | google_compute_instance_template.web_server_template.id 185 | ) 186 | } 187 | 188 | resource "google_compute_instance_group" "web_server_instance_group" { 189 | provider = google 190 | 191 | name = "demo-web-server-group" 192 | description = "Unmanaged instance group containing the web server" 193 | 194 | instances = [ 195 | google_compute_instance_from_template.web_server.id 196 | ] 197 | 198 | named_port { 199 | name = "http" 200 | port = "80" 201 | } 202 | 203 | zone = module.global_variables.zone 204 | } 205 | 206 | # Set up HTTPS global load balancer 207 | 208 | resource "google_compute_health_check" "load_balancer_health_check" { 209 | provider = google 210 | 211 | name = "demo-load-balancer-health-check" 212 | description = "Health check for load balancer web servers" 213 | 214 | timeout_sec = 3 215 | check_interval_sec = 3 216 | healthy_threshold = 1 217 | unhealthy_threshold = 2 218 | 219 | http_health_check { 220 | port_name = "http" 221 | port_specification = "USE_NAMED_PORT" 222 | request_path = "/" 223 | proxy_header = "NONE" 224 | } 225 | 226 | log_config { 227 | enable = true 228 | } 229 | } 230 | 231 | resource "google_compute_backend_service" "web_server_backend_service" { 232 | provider = google 233 | 234 | name = "demo-web-server-backend-service" 235 | description = "Backend service that points to the web server backend" 236 | 237 | load_balancing_scheme = "EXTERNAL" 238 | health_checks = [ 239 | google_compute_health_check.load_balancer_health_check.id 240 | ] 241 | port_name = "http" 242 | protocol = "HTTP" 243 | 244 | backend { 245 | description = "Backend for the web server instance group" 246 | 247 | group = google_compute_instance_group.web_server_instance_group.id 248 | } 249 | 250 | iap { 251 | oauth2_client_id = google_iap_client.demo_iap_client.client_id 252 | oauth2_client_secret = google_iap_client.demo_iap_client.secret 253 | } 254 | } 255 | 256 | # default_url_map - define the URL map for the load balancer 257 | # 258 | # Notes: 259 | # 260 | # (1) The name of the URL map appears as the name of the load balancer in the 261 | # console. 262 | # 263 | # (2) All paths go to the backend web service. 264 | 265 | resource "google_compute_url_map" "default_url_map" { 266 | provider = google 267 | 268 | name = "demo-load-balancer-url-map" 269 | description = "URL map for load balancer,no changes to paths" 270 | 271 | default_service = ( 272 | google_compute_backend_service.web_server_backend_service.id 273 | ) 274 | } 275 | 276 | resource "google_compute_global_address" "external_load_balancer_ip" { 277 | provider = google 278 | 279 | name = "demo-external-load-balancer-ip" 280 | description = "IP address is for frontend of forwarding rule" 281 | } 282 | 283 | resource "google_compute_ssl_certificate" "ssl_cert" { 284 | provider = google 285 | 286 | name_prefix = "demo-certificate-" 287 | description = "SSL certificate for the load balancer" 288 | 289 | private_key = file(module.global_variables.ssl_private_key_file) 290 | certificate = file(module.global_variables.ssl_certificate_file) 291 | 292 | lifecycle { 293 | create_before_destroy = true 294 | } 295 | } 296 | 297 | # ssl_policy - SSL policy for load balancer https proxy 298 | # 299 | # Restrict SSL policy to use a minimum TLS version of 1.2 and also 300 | # limit the ciphers to the MODERN suite. This will help with 301 | # compliance initiatives. 302 | 303 | resource "google_compute_ssl_policy" "ssl_policy" { 304 | provider = google 305 | 306 | name = "demo-ssl-policy" 307 | profile = "MODERN" 308 | min_tls_version = "TLS_1_2" 309 | } 310 | 311 | resource "google_compute_target_https_proxy" "https_proxy" { 312 | provider = google 313 | 314 | name = "demo-https-proxy" 315 | description = "HTTPS proxy for the backend web servers" 316 | 317 | url_map = google_compute_url_map.default_url_map.id 318 | ssl_certificates = [google_compute_ssl_certificate.ssl_cert.id] 319 | ssl_policy = google_compute_ssl_policy.ssl_policy.self_link 320 | } 321 | 322 | resource "google_compute_global_forwarding_rule" "https_forwarding_rule" { 323 | provider = google 324 | 325 | name = "demo-https-forwarding-rule" 326 | description = "This forwarding rule is used to handle HTTPS traffic." 327 | 328 | ip_protocol = "TCP" 329 | load_balancing_scheme = "EXTERNAL" 330 | port_range = "443" 331 | target = google_compute_target_https_proxy.https_proxy.id 332 | ip_address = google_compute_global_address.external_load_balancer_ip.id 333 | } 334 | 335 | # demo_iap_client - OAuth Client for demo 336 | # 337 | # Note: Since there can be only one brand for each project, the format of the 338 | # brand identifier is well-known and does not need to be imported. If more 339 | # brands per project are supported in the future, it may become necessary to 340 | # import the brand into Terraform. 341 | # 342 | # See: "iap_brand" in the Google Cloud Terraform registry for more information. 343 | 344 | resource "google_iap_client" "demo_iap_client" { 345 | provider = google 346 | 347 | display_name = "Demo IAP Client" 348 | brand = "projects/${local.project_number}/brands/${local.project_number}" 349 | } 350 | 351 | resource "google_iap_web_backend_service_iam_binding" "iap_web_binding" { 352 | provider = google 353 | 354 | web_backend_service = ( 355 | google_compute_backend_service.web_server_backend_service.name 356 | ) 357 | role = "roles/iap.httpsResourceAccessor" 358 | members = [ 359 | "user:${module.global_variables.iap_test_user}" 360 | ] 361 | } 362 | 363 | resource "google_iap_tunnel_instance_iam_binding" "iap_tunnel_binding" { 364 | provider = google 365 | 366 | zone = module.global_variables.zone 367 | instance = google_compute_instance_from_template.web_server.name 368 | role = "roles/iap.tunnelResourceAccessor" 369 | members = [ 370 | "user:${module.global_variables.iap_test_user}" 371 | ] 372 | } 373 | -------------------------------------------------------------------------------- /modules/90-build-demo/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | output "Frontend_IP_Address" { 16 | value = google_compute_global_address.external_load_balancer_ip.address 17 | } 18 | -------------------------------------------------------------------------------- /modules/90-build-demo/providers.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | terraform { 16 | required_providers { 17 | google = { 18 | source = "hashicorp/google" 19 | version = ">= 4.16.0" 20 | } 21 | } 22 | } 23 | 24 | provider "google" { 25 | project = module.global_variables.project_id 26 | region = module.global_variables.region 27 | zone = module.global_variables.zone 28 | } 29 | --------------------------------------------------------------------------------