-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.tf
314 lines (235 loc) · 9.54 KB
/
main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# Logging Project CMEK Settings Data Source
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/logging_project_cmek_settings
data "google_logging_project_cmek_settings" "this" {
count = var.cis_2_2_logging_sink_project_id != "" ? 0 : 1
project = google_project.this.project_id
depends_on = [
google_project_service.this
]
}
# Billing Budget Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/billing_budget
resource "google_billing_budget" "project" {
all_updates_rule {
monitoring_notification_channels = [
google_monitoring_notification_channel.this["budget"].name
]
}
amount {
specified_amount {
currency_code = "USD"
units = var.monthly_budget_amount
}
}
billing_account = var.billing_account
budget_filter {
projects = ["projects/${google_project.this.number}"]
}
display_name = "Monthly: ${google_project.this.project_id}"
threshold_rules {
threshold_percent = 0.50
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.75
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 1.0
spend_basis = "CURRENT_SPEND"
}
}
# Project Metadata Item Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_project_metadata_item
# CIS 4.4 Ensure OS login is enabled for a project.
# Enabling OS login binds SSH certificates to IAM users and facilitates effective SSH certificate management.
resource "google_compute_project_metadata_item" "enable_oslogin" {
key = "enable-oslogin"
project = google_project.this.project_id
value = true
depends_on = [
google_project_service.this
]
}
# KMS Crypto Key Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/kms_crypto_key
resource "google_kms_crypto_key" "cis_2_2_logging_sink" {
# See comment below for why we can't use the lifecycle block to prevent destroy on this resource.
# checkov:skip=CKV_GCP_82
count = var.cis_2_2_logging_sink_project_id != "" ? 0 : 1
key_ring = google_kms_key_ring.this.id
labels = var.labels
name = "cis-2-2-logging-sink"
rotation_period = "7776000s"
# We can't use the lifecycle block to prevent destroy on this resource for testing purposes.
# CryptoKeys cannot be deleted from Google Cloud Platform. Destroying a Terraform-managed CryptoKey will
# remove it from state and delete all CryptoKeyVersions, rendering the key unusable, but will not delete
# the resource from the project. When Terraform destroys these keys, any data previously encrypted with
# these keys will be irrecoverable. For this reason, it is strongly recommended that you add lifecycle
# hooks to the resource to prevent accidental destruction.
# lifecycle {
# prevent_destroy = true
# }
}
# KMS Key Ring Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/kms_key_ring
resource "google_kms_key_ring" "this" {
location = var.key_ring_location
name = "default"
project = google_project.this.project_id
depends_on = [
google_project_service.this
]
}
# KMS Crypto Key IAM Member Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/kms_crypto_key_iam_member
resource "google_kms_crypto_key_iam_member" "cis_2_2_logging_sink" {
count = var.cis_2_2_logging_sink_project_id != "" ? 0 : 1
crypto_key_id = google_kms_crypto_key.cis_2_2_logging_sink[0].id
member = "serviceAccount:${data.google_logging_project_cmek_settings.this[0].service_account_id}"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
}
# Logging Metric Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/logging_metric
resource "google_logging_metric" "cis_logging_metrics" {
for_each = local.cis_logging_metrics
description = each.value.description
filter = each.value.filter
name = each.key
project = google_project.this.project_id
}
# We disable _Default logging sink at the organization level to avoid duplicate logs
# https://cloud.google.com/logging/docs/default-settings#disable-default-sink
# gcloud alpha logging settings update --organization=${ORGANIZATION_ID} --disable-default-sink
# gcloud alpha logging settings describe --organization=${ORGANIZATION_ID}
# CIS 2.2 Ensure that sinks are configured for all log entries.
# It is recommended to create a sink that will export copies of all the log entries.
# Project Logging Sink Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/logging_project_sink
resource "google_logging_project_sink" "cis_2_2_logging_sink" {
destination = local.cis_2_2_logging_sink_storage_bucket
name = "cis-2-2-logging-sink"
project = google_project.this.project_id
unique_writer_identity = true
depends_on = [
google_project_service.this
]
}
# Project Logging Bucket Config Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/logging_project_bucket_config
resource "google_logging_project_bucket_config" "cis_2_2_logging_sink" {
count = var.cis_2_2_logging_sink_project_id != "" ? 0 : 1
bucket_id = "cis-2-2-logging-sink"
cmek_settings {
kms_key_name = google_kms_crypto_key.cis_2_2_logging_sink[0].id
}
location = var.key_ring_location
locked = var.cis_2_2_logging_bucket_locked
project = google_project.this.project_id
retention_days = 30
}
# Monitoring Alert Policy Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_alert_policy
resource "google_monitoring_alert_policy" "cis_logging_metrics" {
for_each = local.cis_logging_metrics
combiner = "OR"
conditions {
condition_threshold {
aggregations {
alignment_period = "60s"
cross_series_reducer = "REDUCE_COUNT"
per_series_aligner = "ALIGN_DELTA"
}
duration = "0s"
comparison = "COMPARISON_GT"
filter = "metric.type=\"logging.googleapis.com/user/${each.key}\" AND resource.type=\"${each.value.resource_type}\""
}
display_name = google_logging_metric.cis_logging_metrics[each.key].name
}
display_name = each.value.displayName
documentation {
content = each.value.description
mime_type = "text/markdown"
}
notification_channels = [
google_monitoring_notification_channel.this["security"].name
]
project = google_project.this.project_id
user_labels = merge(
{
status = each.value.status
},
var.labels
)
}
# Monitoring Notification Channel Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_notification_channel
resource "google_monitoring_notification_channel" "this" {
for_each = local.monitoring_notification_channels
description = each.value.description
display_name = each.value.display_name
force_delete = true
labels = {
"email_address" = each.value.email_address
}
project = google_project.this.project_id
type = "email"
user_labels = var.labels
}
# Project Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project
resource "google_project" "this" {
# CIS 3.1 Ensure that the default network does not exist in a project.
# The default network has a pre-configured network configuration that is not suitable for production use.
auto_create_network = false
billing_account = var.billing_account
deletion_policy = var.deletion_policy
folder_id = "folders/${var.folder_id}"
labels = var.labels
name = local.project_id
project_id = local.project_id
}
# IAM Audit Config Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam#google_project_iam_audit_config
# CIS 2.1 Ensure that cloud audit logging is configured properly across all services and all users from a project.
# It is recommended that Cloud Audit Logging is configured to track all admin activities and read, write access to user data.
resource "google_project_iam_audit_config" "cis_2_1" {
project = google_project.this.project_id
service = "allServices"
dynamic "audit_log_config" {
for_each = toset(
[
"ADMIN_READ",
"DATA_READ",
"DATA_WRITE"
]
)
content {
log_type = audit_log_config.key
}
}
}
# Project IAM Member Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam
resource "google_project_iam_member" "cis_2_2" {
# We do not need to add the role to the project if the log bucket and sync are in the same project.
count = var.cis_2_2_logging_sink_project_id == "" ? 0 : 1
member = google_logging_project_sink.cis_2_2_logging_sink.writer_identity
project = local.cis_2_2_logging_sink_project_id
role = "roles/logging.bucketWriter"
}
# Project Service Resource
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_service
resource "google_project_service" "this" {
for_each = local.services
disable_dependent_services = true
project = google_project.this.project_id
service = each.key
}
# Random ID Resource
# https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id
resource "random_id" "this" {
count = var.random_project_id ? 1 : 0
prefix = "tf"
byte_length = "1"
}