Skip to content

Commit d44abb7

Browse files
authored
init (#1)
1 parent bcb4465 commit d44abb7

File tree

12 files changed

+315
-0
lines changed

12 files changed

+315
-0
lines changed

.github/renovate.json5

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": ["github>multani/renovate-config"],
3+
"automerge": true,
4+
}

.github/workflows/lint.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
pull_requests:
6+
- main
7+
8+
branches:
9+
- main
10+
11+
jobs:
12+
terraform:
13+
name: Terraform
14+
runs-on: ubuntu-latest
15+
16+
strategy:
17+
matrix:
18+
directory:
19+
- ./
20+
- ./modules/code
21+
defaults:
22+
run:
23+
working-directory: ${{ matrix.directory }}
24+
25+
steps:
26+
- uses: actions/checkout@v4
27+
28+
- name: Setup Terraform
29+
uses: hashicorp/setup-terraform@v3
30+
with:
31+
terraform_version: 1.7.4
32+
33+
- name: terraform init
34+
run: terraform init -backend=false
35+
36+
- name: Formatting
37+
run: terraform fmt -recursive -check -diff
38+
39+
- name: Validation
40+
run: terraform validate
41+
42+
tflint:
43+
name: TFLint
44+
runs-on: ubuntu-latest
45+
46+
strategy:
47+
matrix:
48+
directory:
49+
- ./
50+
- ./modules/code
51+
defaults:
52+
run:
53+
working-directory: ${{ matrix.directory }}
54+
55+
steps:
56+
- uses: actions/checkout@v4
57+
58+
- name: Setup Terraform
59+
uses: hashicorp/setup-terraform@v3
60+
with:
61+
terraform_version: 1.7.4
62+
63+
- name: Terraform init
64+
run: terraform init -backend=false
65+
66+
- name: Setup tflint
67+
uses: terraform-linters/setup-tflint@v4
68+
with:
69+
# https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting
70+
github_token: ${{ github.token }}
71+
tflint_version: v0.50.3
72+
73+
- name: Init TFLint
74+
run: tflint --init
75+
env:
76+
# https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting
77+
GITHUB_TOKEN: ${{ github.token }}
78+
79+
- name: Run TFLint
80+
run: tflint --format compact --module

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
modules/code/build/

data.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data "google_project" "this" {}

main.tf

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
resource "google_cloudfunctions2_function" "this" {
2+
name = var.name
3+
description = var.description
4+
location = var.location
5+
6+
build_config {
7+
runtime = var.runtime
8+
entry_point = var.entry_point
9+
10+
source {
11+
storage_source {
12+
bucket = var.source_code.bucket
13+
object = var.source_code.object
14+
}
15+
}
16+
}
17+
18+
service_config {
19+
# The service account to run the function as
20+
service_account_email = google_service_account.this.email
21+
22+
timeout_seconds = 60
23+
available_memory = "${var.available_memory}Mi"
24+
max_instance_count = var.max_instance_count
25+
26+
environment_variables = var.environment_variables
27+
}
28+
29+
dynamic "event_trigger" {
30+
for_each = var.event_trigger == null ? [] : [var.event_trigger]
31+
32+
content {
33+
event_type = event_trigger.value.event_type
34+
pubsub_topic = event_trigger.value.pubsub_topic
35+
36+
service_account_email = (
37+
event_trigger.value.service_account_email == null ?
38+
google_service_account.this.email :
39+
event_trigger.value.service_account_email
40+
)
41+
42+
retry_policy = event_trigger.value.retry_policy
43+
trigger_region = (
44+
event_trigger.value.trigger_region == null ?
45+
var.location :
46+
event_trigger.value.trigger_region
47+
)
48+
}
49+
}
50+
}

modules/code/main.tf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
data "archive_file" "code" {
2+
type = "zip"
3+
4+
source_dir = var.source_dir
5+
6+
output_file_mode = "0666"
7+
output_path = "${path.module}/build/${var.name}.zip"
8+
}
9+
10+
resource "google_storage_bucket_object" "this" {
11+
# Interpolate the hash of the archive file in the name: when the content of
12+
# the ZIP file changes (because the source code changed), the bucket object
13+
# will be recreated and this will also force the recreation/update of the
14+
# Google Cloud Function.
15+
name = "${var.name}-${data.archive_file.code.output_md5}.zip"
16+
17+
bucket = var.bucket_name
18+
source = data.archive_file.code.output_path
19+
20+
metadata = var.metadata
21+
}

modules/code/output.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
output "bucket" {
2+
value = google_storage_bucket_object.this.bucket
3+
}
4+
5+
output "object" {
6+
value = google_storage_bucket_object.this.name
7+
}

modules/code/providers.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
terraform {
2+
required_providers {
3+
archive = {
4+
source = "hashicorp/archive"
5+
}
6+
7+
google = {
8+
source = "hashicorp/google"
9+
}
10+
}
11+
}

modules/code/variables.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
variable "source_dir" {
2+
description = "The directory in which the source code of the Cloud Function is"
3+
type = string
4+
}
5+
6+
variable "name" {
7+
description = "The name of the Cloud Function, as stored in the Google Cloud Storage bucket"
8+
type = string
9+
}
10+
11+
variable "bucket_name" {
12+
description = "The Google Cloud Storage bucket name to store the Cloud Function code in"
13+
type = string
14+
}
15+
16+
variable "metadata" {
17+
description = "Key/value to associate with the source code"
18+
default = {}
19+
type = map(string)
20+
}

outputs.tf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
output "name" {
2+
description = "The name of the function"
3+
value = google_cloudfunctions2_function.this.name
4+
}
5+
6+
output "location" {
7+
description = "The location of the function"
8+
value = google_cloudfunctions2_function.this.location
9+
}
10+
11+
output "service_account_email" {
12+
description = "The service account email the function runs as"
13+
value = google_service_account.this.email
14+
}
15+
16+
output "service_account_name" {
17+
description = "The FQDN to the service account the function runs as"
18+
value = google_service_account.this.name
19+
}
20+
21+
output "uri" {
22+
description = "The URI to call the function"
23+
value = google_cloudfunctions2_function.this.service_config[0].uri
24+
}

service-account.tf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
locals {
2+
sa_name = var.service_account.name == null ? "fun-${var.name}" : var.service_account.name
3+
4+
sa_description = var.service_account.description == null ? "User for the Cloud Function: ${var.name}" : var.service_account.description
5+
}
6+
7+
# The user to run the functions as
8+
resource "google_service_account" "this" {
9+
account_id = local.sa_name
10+
description = local.sa_description
11+
}
12+
13+
# Write traces
14+
resource "google_project_iam_member" "tracing" {
15+
# https://cloud.google.com/trace/docs/iam#roles
16+
role = "roles/cloudtrace.agent"
17+
member = "serviceAccount:${google_service_account.this.email}"
18+
project = data.google_project.this.project_id
19+
}

variables.tf

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
variable "name" {
2+
description = "The name of the function"
3+
type = string
4+
}
5+
6+
variable "description" {
7+
description = "The description of the function"
8+
type = string
9+
}
10+
11+
variable "location" {
12+
description = "The location (region) of the function"
13+
type = string
14+
}
15+
16+
variable "runtime" {
17+
description = "Which runtime to run the function with"
18+
type = string
19+
}
20+
21+
variable "entry_point" {
22+
description = "The entry point to execute the function from"
23+
type = string
24+
}
25+
26+
27+
variable "source_code" {
28+
description = "The source code of the function"
29+
type = object({
30+
bucket = string
31+
object = string
32+
})
33+
}
34+
35+
variable "available_memory" {
36+
description = "The memory to allocate to the function in MB"
37+
type = number
38+
default = 256
39+
}
40+
41+
variable "max_instance_count" {
42+
description = "The maximum number of instances to run"
43+
type = number
44+
default = 1
45+
}
46+
47+
variable "environment_variables" {
48+
description = "The environment variables for the function"
49+
type = map(string)
50+
default = {}
51+
}
52+
53+
variable "service_account" {
54+
description = "Information about the service account used by the function"
55+
default = {}
56+
57+
type = object({
58+
name = optional(string, null)
59+
description = optional(string, null)
60+
})
61+
}
62+
63+
variable "event_trigger" {
64+
description = "The event triggering the function"
65+
66+
default = null
67+
68+
type = object({
69+
event_type = string
70+
pubsub_topic = string
71+
72+
service_account_email = optional(string, null)
73+
74+
retry_policy = optional(string, "RETRY_POLICY_DO_NOT_RETRY")
75+
trigger_region = optional(string, null)
76+
})
77+
}

0 commit comments

Comments
 (0)