mirror of
https://github.com/imjasonh/terraform-playground
synced 2026-07-08 07:44:57 +00:00
Merge pull request #6 from imjasonh/copilot/sub-pr-3-another-one
This commit is contained in:
commit
c20be36cd2
3 changed files with 51 additions and 71 deletions
|
|
@ -1,60 +1,61 @@
|
|||
#cloud-config
|
||||
# This cloud-init configuration defines a systemd service to run the Docker container
|
||||
# This cloud-init configuration defines systemd services to run Docker containers
|
||||
# on Container-Optimized OS (COS).
|
||||
|
||||
write_files:
|
||||
- path: /etc/systemd/system/${container_name}.service
|
||||
%{ for name, container in containers ~}
|
||||
- path: /etc/systemd/system/${name}.service
|
||||
permissions: 0644
|
||||
owner: root
|
||||
content: |
|
||||
[Unit]
|
||||
Description=Containerized application: ${container_name}
|
||||
Description=Containerized application: ${name}
|
||||
# Wait for the Docker socket to be ready
|
||||
Wants=docker.socket
|
||||
After=docker.service
|
||||
|
||||
[Service]
|
||||
# Crucial for persistence: ensure the service restarts on exit.
|
||||
Restart=${restart_policy}
|
||||
Restart=${container.restart_policy}
|
||||
RestartSec=5s
|
||||
|
||||
# Stop and remove any pre-existing container with the same name.
|
||||
ExecStartPre=/usr/bin/docker stop ${container_name} || true
|
||||
ExecStartPre=/usr/bin/docker rm ${container_name} || true
|
||||
ExecStartPre=/usr/bin/docker stop ${name} || true
|
||||
ExecStartPre=/usr/bin/docker rm ${name} || true
|
||||
|
||||
# Pull the latest version of the image before starting.
|
||||
ExecStartPre=/usr/bin/docker pull ${container_image}
|
||||
# Pull the image before starting.
|
||||
ExecStartPre=/usr/bin/docker pull ${container.image}
|
||||
|
||||
# The main execution command: docker run.
|
||||
# We use 'docker run --rm' to ensure clean removal after failure/stop.
|
||||
ExecStart=/usr/bin/docker run \
|
||||
--name ${container_name} \
|
||||
%{ for key, value in container_env ~}
|
||||
-e ${key}="${value}" \
|
||||
%{ endfor ~}
|
||||
${container_image} \
|
||||
%{ if container_command != "" ~}
|
||||
"${container_command}" \
|
||||
%{ endif ~}
|
||||
%{ if length(container_args) > 0 ~}
|
||||
%{ for arg in container_args ~}
|
||||
# Escape single quotes in arguments by ending the quoted string, inserting an escaped quote, and resuming the quoted string.
|
||||
# This pattern: replace(arg, "'", "'\\''") is standard for safely passing single quotes in shell.
|
||||
--name ${name} \
|
||||
%{ for e in container.env ~}
|
||||
-e ${e.name}="${e.value}" \
|
||||
%{ endfor ~}
|
||||
${container.image} \
|
||||
%{ if container.command != "" ~}
|
||||
"${container.command}" \
|
||||
%{ endif ~}
|
||||
%{ for arg in container.args ~}
|
||||
# Escape single quotes: end quoted string, add escaped quote, resume quoted string
|
||||
'${replace(arg, "'", "'\\''")}' \
|
||||
%{ endfor ~}
|
||||
%{ endif ~}
|
||||
%{ endfor ~}
|
||||
|
||||
|
||||
# ExecStop is called when the service is stopped manually.
|
||||
ExecStop=/usr/bin/docker stop ${container_name}
|
||||
ExecStop=/usr/bin/docker stop ${name}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
runcmd:
|
||||
# Reload the systemd configuration to recognize the new service file.
|
||||
- systemctl daemon-reload
|
||||
# Enable the service to start automatically on subsequent boots.
|
||||
- systemctl enable ${container_name}.service
|
||||
# Start the service immediately.
|
||||
- systemctl start ${container_name}.service
|
||||
%{ endfor ~}
|
||||
|
||||
runcmd:
|
||||
# Reload the systemd configuration to recognize the new service files.
|
||||
- systemctl daemon-reload
|
||||
%{ for name, container in containers ~}
|
||||
# Enable and start ${name} service.
|
||||
- systemctl enable ${name}.service
|
||||
- systemctl start ${name}.service
|
||||
%{ endfor ~}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,7 @@ data "google_compute_image" "source_image" {
|
|||
# Render the cloud-init YAML template using dynamic module inputs
|
||||
locals {
|
||||
rendered_cloud_init = templatefile("${path.module}/cloud-init.yaml.tftpl", {
|
||||
container_name = var.container_name,
|
||||
container_image = var.container_image,
|
||||
restart_policy = var.restart_policy,
|
||||
container_env = var.container_env,
|
||||
container_command = var.container_command,
|
||||
container_args = var.container_args,
|
||||
containers = var.containers,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,44 +15,28 @@ variable "machine_type" {
|
|||
default = "e2-medium"
|
||||
}
|
||||
|
||||
variable "container_image" {
|
||||
description = "The container image to run, must be referenced by digest (e.g., 'gcr.io/my-project/my-app@sha256:abc123...')."
|
||||
type = string
|
||||
variable "containers" {
|
||||
description = "A map of containers to run on the VM. Each key is the container name, and the value specifies the container configuration."
|
||||
type = map(object({
|
||||
image = string
|
||||
command = optional(string, "")
|
||||
args = optional(list(string), [])
|
||||
env = optional(list(object({
|
||||
name = string
|
||||
value = string
|
||||
})), [])
|
||||
restart_policy = optional(string, "always")
|
||||
}))
|
||||
|
||||
validation {
|
||||
condition = can(regex("^.+@sha256:[a-f0-9]{64}$", var.container_image))
|
||||
error_message = "The container_image must be referenced by digest (e.g., 'gcr.io/my-project/my-app@sha256:<64 hex chars>')."
|
||||
condition = length(var.containers) > 0
|
||||
error_message = "At least one container must be specified."
|
||||
}
|
||||
}
|
||||
|
||||
variable "container_name" {
|
||||
description = "The name to assign to the running Docker container."
|
||||
type = string
|
||||
default = "gce-container-app"
|
||||
}
|
||||
|
||||
variable "restart_policy" {
|
||||
description = "The systemd/Docker restart policy (e.g., 'always', 'on-failure', 'no')."
|
||||
type = string
|
||||
default = "always"
|
||||
}
|
||||
|
||||
variable "container_env" {
|
||||
description = "A map of environment variables to set in the container."
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "container_command" {
|
||||
description = "The optional command to override the ENTRYPOINT (e.g., '/bin/bash')."
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "container_args" {
|
||||
description = "Optional arguments to pass to the container command."
|
||||
type = list(string)
|
||||
default = []
|
||||
validation {
|
||||
condition = alltrue([for name, c in var.containers : can(regex("^.+@sha256:[a-f0-9]{64}$", c.image))])
|
||||
error_message = "All container images must be referenced by digest (e.g., 'gcr.io/my-project/my-app@sha256:<64 hex chars>')."
|
||||
}
|
||||
}
|
||||
|
||||
variable "service_account_email" {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue