Skip to content

Commit 730b4bb

Browse files
authored
chore: Add example with templated and bind mounted config file (#68)
1 parent bff2870 commit 730b4bb

File tree

23 files changed

+764
-5
lines changed

23 files changed

+764
-5
lines changed

.kitchen.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,27 @@ suites:
7575
key_files:
7676
- ./test/fixtures/instance_with_attached_disk/ssh/key
7777
user: user
78+
- name: "instance_with_config_file"
79+
driver:
80+
name: "terraform"
81+
command_timeout: 1800
82+
root_module_directory: test/fixtures/instance_with_config_file
83+
verifier:
84+
name: terraform
85+
color: false
86+
systems:
87+
- name: system
88+
backend: local
89+
controls:
90+
- gce
91+
- name: remote
92+
backend: ssh
93+
controls:
94+
- docker
95+
hosts_output: ipv4
96+
key_files:
97+
- ./test/fixtures/instance_with_config_file/ssh/key
98+
user: user
7899
- name: "managed_instance_group"
79100
excludes:
80101
- local

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# Make will use bash instead of sh
1919
SHELL := /usr/bin/env bash
2020

21-
DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 0
21+
DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 0.12.0
2222
DOCKER_IMAGE_DEVELOPER_TOOLS := cft/developer-tools
2323
REGISTRY_URL := gcr.io/cloud-foundation-cicd
2424

build/int.cloudbuild.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ tags:
3838
- 'integration'
3939
substitutions:
4040
_DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools'
41-
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0'
41+
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.12.0'

build/lint.cloudbuild.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ tags:
2121
- 'lint'
2222
substitutions:
2323
_DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools'
24-
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0'
24+
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.12.0'

examples/instance_with_attached_disk/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This example illustrates how to deploy and expose a container to a Google Comput
77

88
| Name | Description | Type | Default | Required |
99
|------|-------------|:----:|:-----:|:-----:|
10-
| additional\_metadata | Additional metadata to attach to the instance | map | `<map>` | no |
10+
| additional\_metadata | Additional metadata to attach to the instance | map(string) | `<map>` | no |
1111
| client\_email | Service account email address | string | `""` | no |
1212
| image | The Docker image to deploy to GCE instances | string | n/a | yes |
1313
| image\_port | The port the image exposes for HTTP requests | string | n/a | yes |

examples/instance_with_attached_disk/variables.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ variable "zone" {
5252
}
5353

5454
variable "additional_metadata" {
55-
type = "map"
55+
type = map(string)
5656
description = "Additional metadata to attach to the instance"
5757
default = {}
5858
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
terraform.tfvars
2+
.terraform
3+
terraform.tfstate.d
4+
terraform.tfstate.backup
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Instance with Config File
2+
3+
This example illustrates how to deploy and expose a container to a Google Compute Engine instance in GCP, with an templated config file mounted into the container.
4+
5+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
6+
## Inputs
7+
8+
| Name | Description | Type | Default | Required |
9+
|------|-------------|:----:|:-----:|:-----:|
10+
| additional\_metadata | Additional metadata to attach to the instance | map(string) | `<map>` | no |
11+
| client\_email | Service account email address | string | `""` | no |
12+
| cos\_image\_name | The forced COS image to use instead of latest | string | `"cos-stable-77-12371-89-0"` | no |
13+
| instance\_name | The desired name to assign to the deployed instance | string | `"hello-world-container-vm"` | no |
14+
| project\_id | The project ID to deploy resources into | string | n/a | yes |
15+
| subnetwork | The name of the subnetwork to deploy instances into | string | n/a | yes |
16+
| subnetwork\_project | The project ID where the desired subnetwork is provisioned | string | n/a | yes |
17+
| zone | The GCP zone to deploy instances into | string | n/a | yes |
18+
19+
## Outputs
20+
21+
| Name | Description |
22+
|------|-------------|
23+
| container | The container metadata provided to the module |
24+
| instance\_name | The deployed instance name |
25+
| ipv4 | The public IP address of the deployed instance |
26+
| vm\_container\_label | The instance label containing container configuration |
27+
| volumes | The volume metadata provided to the module |
28+
29+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
30+
31+
## Running
32+
33+
To provision this example, run the following from within this directory:
34+
35+
- `terraform init` to get plugins
36+
- `terraform plan` to dry-run the infrastructure changes
37+
- `terraform apply` to apply the infrastructure changes
38+
- `terraform destroy` to tear down the created infrastructure
39+
40+
## Debugging
41+
42+
SSH into the VM instance (e.g. through the cloud console) and run the following commands.
43+
44+
To verify that the startup script wrote the config file:
45+
46+
```
47+
$ cat /etc/hello-app/config.json
48+
{
49+
"instance_name": "hello-world-container-vm-60b69fa4",
50+
"boot_timestamp": "2020-09-30T19:37:51,065136954+00:00",
51+
}
52+
```
53+
54+
To verify that the config file can be read from inside the container:
55+
56+
```
57+
$ docker exec "$(docker ps | grep hello-app | cut -f 1 -d ' ')" cat /config.json
58+
{
59+
"instance_name": "hello-world-container-vm-60b69fa4",
60+
"boot_timestamp": "2020-09-30T19:37:51,065136954+00:00",
61+
}
62+
```
63+
64+
To debug the startup script, see [viewing startup script logs](https://cloud.google.com/compute/docs/startupscript#viewing_startup_script_logs) and [rerunning a startup script](https://cloud.google.com/compute/docs/startupscript#rerunthescript).
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* Copyright 2020 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
provider "google" {
18+
project = var.project_id
19+
version = "~> 2.20"
20+
}
21+
22+
provider "template" {
23+
version = "~> 2.1"
24+
}
25+
26+
locals {
27+
instance_name = format("%s-%s", var.instance_name, substr(md5(module.gce-container.container.image), 0, 8))
28+
config_path = "/etc/hello-app/config.json"
29+
}
30+
31+
module "gce-container" {
32+
source = "../../"
33+
34+
cos_image_name = var.cos_image_name
35+
36+
container = {
37+
image = "gcr.io/google-samples/hello-app:1.0"
38+
39+
volumeMounts = [
40+
{
41+
mountPath = "/config.json"
42+
name = "config"
43+
readOnly = true
44+
},
45+
]
46+
}
47+
48+
volumes = [
49+
{
50+
name = "config"
51+
hostPath = {
52+
path = local.config_path
53+
}
54+
},
55+
]
56+
57+
restart_policy = "Always"
58+
}
59+
60+
data "template_file" "startup_script" {
61+
template = "${file("${path.module}/startup.sh.tpl")}"
62+
vars = {
63+
instance_name = local.instance_name
64+
config_path = local.config_path
65+
}
66+
}
67+
68+
resource "google_compute_instance" "vm" {
69+
project = var.project_id
70+
name = local.instance_name
71+
machine_type = "n1-standard-1"
72+
zone = var.zone
73+
74+
boot_disk {
75+
initialize_params {
76+
image = module.gce-container.source_image
77+
}
78+
}
79+
80+
network_interface {
81+
subnetwork_project = var.subnetwork_project
82+
subnetwork = var.subnetwork
83+
access_config {}
84+
}
85+
86+
tags = ["container-vm-example"]
87+
88+
metadata = merge(
89+
{
90+
gce-container-declaration = module.gce-container.metadata_value
91+
google-logging-enabled = "true"
92+
google-monitoring-enabled = "true"
93+
},
94+
var.additional_metadata,
95+
)
96+
97+
labels = {
98+
container-vm = module.gce-container.vm_container_label
99+
}
100+
101+
service_account {
102+
email = var.client_email
103+
scopes = [
104+
"https://www.googleapis.com/auth/cloud-platform",
105+
]
106+
}
107+
108+
metadata_startup_script = data.template_file.startup_script.rendered
109+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Copyright 2020 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
output "instance_name" {
18+
description = "The deployed instance name"
19+
value = google_compute_instance.vm.name
20+
}
21+
22+
output "vm_container_label" {
23+
description = "The instance label containing container configuration"
24+
value = module.gce-container.vm_container_label
25+
}
26+
27+
output "container" {
28+
description = "The container metadata provided to the module"
29+
value = module.gce-container.container
30+
}
31+
32+
output "volumes" {
33+
description = "The volume metadata provided to the module"
34+
value = module.gce-container.volumes
35+
}
36+
37+
output "ipv4" {
38+
description = "The public IP address of the deployed instance"
39+
value = google_compute_instance.vm.network_interface.0.access_config.0.nat_ip
40+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2020 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# Generates a config file with templated values.
18+
#
19+
# Terraform interpolation uses standard shell interpolation syntax ($).
20+
# So shell interpolation inside a Terraform template must be escaped ($$).
21+
# Command substitution does not need escaping ($).
22+
23+
set -o errexit -o nounset -o pipefail -o posix
24+
25+
boot_timestamp="$(date --iso-8601=ns)"
26+
27+
mkdir -p "$(dirname "${config_path}")"
28+
29+
cat > "${config_path}" << EOF
30+
{
31+
"instance_name": "${instance_name}",
32+
"boot_timestamp": "$${boot_timestamp}",
33+
}
34+
EOF
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright 2020 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
variable "project_id" {
18+
description = "The project ID to deploy resources into"
19+
}
20+
21+
variable "subnetwork_project" {
22+
description = "The project ID where the desired subnetwork is provisioned"
23+
}
24+
25+
variable "subnetwork" {
26+
description = "The name of the subnetwork to deploy instances into"
27+
}
28+
29+
variable "instance_name" {
30+
description = "The desired name to assign to the deployed instance"
31+
default = "hello-world-container-vm"
32+
}
33+
34+
variable "zone" {
35+
description = "The GCP zone to deploy instances into"
36+
type = string
37+
}
38+
39+
variable "additional_metadata" {
40+
type = map(string)
41+
description = "Additional metadata to attach to the instance"
42+
default = {}
43+
}
44+
45+
variable "client_email" {
46+
description = "Service account email address"
47+
type = string
48+
default = ""
49+
}
50+
51+
variable "cos_image_name" {
52+
description = "The forced COS image to use instead of latest"
53+
default = "cos-stable-77-12371-89-0"
54+
}

0 commit comments

Comments
 (0)