Skip to content

Commit 37ea3b1

Browse files
committed
Configure the database with Terraform.
1 parent b6f36ce commit 37ea3b1

File tree

3 files changed

+165
-0
lines changed

3 files changed

+165
-0
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ node_modules/
88
.env
99
.env.production
1010

11+
# Terraform
12+
.terraform/
13+
terraform.tfvars
14+
terraform.tfstate*
15+
1116
# C++
1217
*.o
1318
import/tofirebase

db/.terraform.lock.hcl

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

db/main.tf

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
terraform {
2+
required_providers {
3+
postgresql = {
4+
source = "cyrilgdn/postgresql"
5+
version = "1.18.0"
6+
}
7+
}
8+
}
9+
10+
variable "pg_host" {
11+
type = string
12+
default = "localhost"
13+
}
14+
variable "pg_port" {
15+
type = number
16+
default = 5432
17+
}
18+
variable "pg_username" {
19+
type = string
20+
default = "postgres"
21+
}
22+
variable "pg_password" {
23+
type = string
24+
sensitive = true
25+
}
26+
variable "pg_database" {
27+
type = string
28+
default = "postgres"
29+
}
30+
31+
variable "pg_cookbook_prod_admin_password" {
32+
type = string
33+
sensitive = true
34+
}
35+
variable "pg_cookbook_prod_webserver_password" {
36+
type = string
37+
sensitive = true
38+
}
39+
variable "pg_cookbook_staging_admin_password" {
40+
type = string
41+
sensitive = true
42+
}
43+
variable "pg_cookbook_staging_webserver_password" {
44+
type = string
45+
sensitive = true
46+
}
47+
48+
provider "postgresql" {
49+
host = var.pg_host
50+
port = var.pg_port
51+
database = var.pg_database
52+
username = var.pg_username
53+
password = var.pg_password
54+
sslmode = "disable"
55+
connect_timeout = 15
56+
expected_version = 14
57+
}
58+
59+
resource "postgresql_role" "cookbook_prod_admin" {
60+
name = "cookbook_prod_admin"
61+
login = true
62+
password = var.pg_cookbook_prod_admin_password
63+
}
64+
resource "postgresql_role" "cookbook_prod_webserver" {
65+
name = "cookbook_prod_webserver"
66+
login = true
67+
password = var.pg_cookbook_prod_webserver_password
68+
}
69+
70+
resource "postgresql_database" "cookbook_prod" {
71+
name = "cookbook_prod"
72+
owner = "cookbook_prod_admin"
73+
template = "template0"
74+
encoding = "UTF8"
75+
lc_collate = "en_US.utf8"
76+
lc_ctype = "en_US.utf8"
77+
}
78+
79+
resource "postgresql_role" "cookbook_staging_admin" {
80+
name = "cookbook_staging_admin"
81+
login = true
82+
password = var.pg_cookbook_staging_admin_password
83+
}
84+
resource "postgresql_role" "cookbook_staging_webserver" {
85+
name = "cookbook_staging_webserver"
86+
login = true
87+
password = var.pg_cookbook_staging_webserver_password
88+
}
89+
90+
resource "postgresql_database" "cookbook_staging" {
91+
name = "cookbook_staging"
92+
owner = "cookbook_staging_admin"
93+
template = "template0"
94+
encoding = "UTF8"
95+
lc_collate = "en_US.utf8"
96+
lc_ctype = "en_US.utf8"
97+
}
98+
99+
// Grant privileges to the webserver. The server needs to read and update tables and "use"
100+
// sequences, both for existing tables and new ones.
101+
locals {
102+
privileges = [{
103+
object_type = "table"
104+
privileges = ["SELECT", "INSERT", "UPDATE", "DELETE"]
105+
}, {
106+
object_type = "sequence"
107+
privileges = ["USAGE"]
108+
}]
109+
110+
environments = ["staging", "prod"]
111+
112+
environment_privileges = { for pair in setproduct(local.environments, local.privileges) :
113+
"${pair[0]}.${pair[1].object_type}" => { environment : pair[0], privilege : pair[1] }
114+
}
115+
}
116+
117+
resource "postgresql_default_privileges" "cookbook_webserver" {
118+
for_each = local.environment_privileges
119+
120+
database = "cookbook_${each.value.environment}"
121+
role = "cookbook_${each.value.environment}_webserver"
122+
schema = "public"
123+
owner = "cookbook_${each.value.environment}_admin"
124+
object_type = each.value.privilege.object_type
125+
privileges = each.value.privilege.privileges
126+
}
127+
resource "postgresql_grant" "cookbook_webserver" {
128+
for_each = local.environment_privileges
129+
130+
database = "cookbook_${each.value.environment}"
131+
role = "cookbook_${each.value.environment}_webserver"
132+
schema = "public"
133+
object_type = each.value.privilege.object_type
134+
objects = [] # All objects of this type.
135+
privileges = each.value.privilege.privileges
136+
}

0 commit comments

Comments
 (0)