Skip to content

Commit 91bcc4d

Browse files
authored
feat: (IAC-1065) Add Hadolint, ShellCheck and TFLint Checks via GitHub Actions (#183)
1 parent 9af7b11 commit 91bcc4d

File tree

18 files changed

+305
-131
lines changed

18 files changed

+305
-131
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: Linter Analysis
2+
on:
3+
push:
4+
branches: [ '*' ] # '*' will cause the workflow to run on all commits to all branches.
5+
6+
jobs:
7+
# Hadolint: Job-1
8+
Hadolint:
9+
name: Hadolint
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout Repo
13+
uses: actions/checkout@v3
14+
15+
- name: Run Hadolint Action
16+
uses: jbergstroem/[email protected]
17+
with:
18+
dockerfile: ./Dockerfile
19+
config_file: linting-configs/.hadolint.yaml
20+
error_level: 1 # Fail CI based on hadolint output (-1: never, 0: error, 1: warning, 2: info)
21+
22+
# ShellCheck: Job-2
23+
ShellCheck:
24+
name: ShellCheck
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout Repo
28+
uses: actions/checkout@v3
29+
30+
- name: Run ShellCheck Action
31+
uses: ludeeus/action-shellcheck@master
32+
with:
33+
severity: error
34+
35+
# TFLint: Job-3
36+
TFLint:
37+
name: TFLint
38+
runs-on: ubuntu-latest
39+
steps:
40+
- name: Checkout Repo
41+
uses: actions/checkout@v3
42+
43+
- name: Cache Plugin Directory
44+
uses: actions/cache@v3
45+
with:
46+
path: ~/.tflint.d/plugins
47+
key: ubuntu-latest-tflint-${{ hashFiles('.tflint.hcl') }}
48+
49+
- name: Setup TFLint
50+
uses: terraform-linters/[email protected]
51+
with:
52+
tflint_version: latest
53+
github_token: ${{ secrets.LINTER_TOKEN }}
54+
55+
- name: Initializing viya4-iac-gcp
56+
run: terraform init
57+
58+
# Necessary so we can recursively tflint our modules folder
59+
# not needed for regular project use.
60+
- name: Initializing viya4-iac-gcp/modules/google_vm
61+
run: terraform -chdir=modules/google_vm init
62+
63+
- name: Initializing TFLint
64+
run: TFLINT_LOG=info tflint --init -c "$(pwd)/linting-configs/.tflint.hcl"
65+
66+
- name: Run TFLint Action
67+
run: TFLINT_LOG=info tflint -c "$(pwd)/linting-configs/.tflint.hcl" --recursive

Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ COPY --from=terraform /bin/terraform /bin/terraform
1515
COPY . .
1616

1717
RUN apt-get update && apt-get upgrade -y \
18-
&& apt-get install -y jq \
18+
&& apt-get install --no-install-recommends -y jq \
19+
&& apt-get clean \
20+
&& rm -rf /var/lib/apt/lists/* \
1921
&& curl -sLO https://storage.googleapis.com/kubernetes-release/release/v$KUBECTL_VERSION/bin/linux/amd64/kubectl \
2022
&& chmod 755 ./kubectl /viya4-iac-gcp/docker-entrypoint.sh \
2123
&& mv ./kubectl /usr/local/bin/kubectl \

docker-entrypoint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ set -e
99
echo "viya4-iac-gcp:*:$(id -u):$(id -g):,,,:/viya4-iac-gcp:/bin/bash" >> /etc/passwd
1010
echo "viya4-iac-gcp:*:$(id -G | cut -d' ' -f 2)" >> /etc/group
1111

12-
exec /bin/terraform $@
12+
exec /bin/terraform "$@"

linting-configs/.hadolint.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ignored:
2+
# Specify version with apt-get install -y <package>=<version> : https://github.com/hadolint/hadolint/wiki/DL3008
3+
- DL3008

linting-configs/.shellcheckrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Review 'man shellcheck' section 'RC FILES' for instructions on adding directives.
2+
3+
# Allow using `which` since it gives full paths and is common enough
4+
# https://github.com/koalaman/shellcheck/wiki/SC2230
5+
disable=SC2230

linting-configs/.tflint.hcl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# For more information on configuring TFlint; see https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/config.md
2+
3+
# For more information on plugins see https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md
4+
5+
# For more information on TFlint Ruleset for Terraform; see https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.3.0/docs/rules/README.md
6+
7+
# For more information on TFlint Ruleset for GCP, see https://github.com/terraform-linters/tflint-ruleset-google/blob/master/README.md
8+
9+
config {
10+
# Enables module inspection.
11+
module = true
12+
}
13+
14+
plugin "google" {
15+
enabled = true
16+
version = "0.23.1"
17+
source = "github.com/terraform-linters/tflint-ruleset-google"
18+
}
19+
20+
plugin "terraform" {
21+
enabled = true
22+
preset = "recommended"
23+
}
24+
25+
# We specify the versions and providers in the top level versions.tf.
26+
# This stops it from throwing a warning when scanning our modules
27+
# in viya4-iac-gcp/modules/
28+
rule "terraform_required_version" {
29+
enabled = false
30+
}
31+
rule "terraform_required_providers" {
32+
enabled = false
33+
}

locals.tf

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ locals {
1212
is_region = var.location != "" ? var.location == regex("^[a-z0-9]*-[a-z0-9]*", var.location) : false
1313
first_zone = length(data.google_compute_zones.available.names) > 0 ? data.google_compute_zones.available.names[0] : ""
1414
# all_zones = length(data.google_compute_zones.available.names) > 0 ? join(",", [for item in data.google_compute_zones.available.names : format("%s", item)]) : ""
15-
zone = (var.location != "" ? (local.is_region ? local.first_zone : var.location) : (data.google_client_config.current.zone == "" ? local.first_zone : data.google_client_config.current.zone))
16-
location = var.location != "" ? var.location : local.zone
15+
zone = (var.location != "" ? (local.is_region ? local.first_zone : var.location) : (data.google_client_config.current.zone == "" ? local.first_zone : data.google_client_config.current.zone))
1716

1817
# CIDRs/Network
1918
default_public_access_cidrs = var.default_public_access_cidrs == null ? [] : var.default_public_access_cidrs
@@ -38,11 +37,6 @@ locals {
3837
NoExecute = "NO_EXECUTE"
3938
}
4039

41-
# kube config
42-
service_account_name = "${var.prefix}-cluster-admin-sa"
43-
cluster_role_binding_name = "${var.prefix}-cluster-admin-crb"
44-
service_account_secret_name = "${var.prefix}-sa-secret"
45-
4640
node_pools_and_accelerator_taints = {
4741
for node_pool, settings in var.node_pools : node_pool => {
4842
accelerator_count = settings.accelerator_count
@@ -55,7 +49,7 @@ locals {
5549
vm_type = settings.vm_type
5650
node_taints = settings.accelerator_count > 0 ? concat(settings.node_taints, ["nvidia.com/gpu=present:NoSchedule"]) : settings.node_taints
5751
initial_node_count = max(local.initial_node_count, settings.min_nodes)
58-
node_locations = var.nodepools_locations != "" && var.nodepools_locations != null ? var.nodepools_locations : local.zone
52+
node_locations = var.nodepools_locations != "" && var.nodepools_locations != null ? var.nodepools_locations : local.zone
5953
}
6054
}
6155

@@ -71,7 +65,7 @@ locals {
7165
"accelerator_count" = 0
7266
"accelerator_type" = ""
7367
"initial_node_count" = var.default_nodepool_min_nodes
74-
"node_locations" = var.default_nodepool_locations != "" && var.default_nodepool_locations != null ? var.default_nodepool_locations : local.zone
68+
"node_locations" = var.default_nodepool_locations != "" && var.default_nodepool_locations != null ? var.default_nodepool_locations : local.zone
7569
}
7670
})
7771

@@ -87,7 +81,7 @@ locals {
8781
gke_subnet_cidr = length(var.subnet_names) == 0 ? var.gke_subnet_cidr : module.vpc.subnets["gke"].ip_cidr_range
8882
misc_subnet_cidr = length(var.subnet_names) == 0 ? var.misc_subnet_cidr : module.vpc.subnets["misc"].ip_cidr_range
8983

90-
gke_pod_range_index = length(var.subnet_names) == 0 ? index(module.vpc.subnets["gke"].secondary_ip_range.*.range_name, local.subnet_names["gke_pods_range_name"]) : 0
84+
gke_pod_range_index = length(var.subnet_names) == 0 ? index(module.vpc.subnets["gke"].secondary_ip_range[*].range_name, local.subnet_names["gke_pods_range_name"]) : 0
9185
gke_pod_subnet_cidr = length(var.subnet_names) == 0 ? var.gke_pod_subnet_cidr : module.vpc.subnets["gke"].secondary_ip_range[local.gke_pod_range_index].ip_cidr_range
9286

9387
filestore_size_in_gb = (
@@ -110,8 +104,8 @@ locals {
110104
ssl_enforcement_enabled : local.postgres_servers[k].ssl_enforcement_enabled,
111105
connection_name : module.postgresql[k].instance_connection_name,
112106
server_public_ip : length(local.postgres_public_access_cidrs) > 0 ? module.postgresql[k].public_ip_address : null,
113-
server_cert : module.postgresql[k].instance_server_ca_cert.0.cert,
114-
service_account : module.sql_proxy_sa.0.service_account.email,
107+
server_cert : module.postgresql[k].instance_server_ca_cert[0].cert,
108+
service_account : module.sql_proxy_sa[0].service_account.email,
115109
internal : false,
116110
}
117111
} : {}

main.tf

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ resource "kubernetes_config_map" "sas_iac_buildinfo" {
5151
}
5252

5353
data = {
54-
git-hash = lookup(data.external.git_hash.0.result, "git-hash")
54+
git-hash = lookup(data.external.git_hash[0].result, "git-hash")
5555
iac-tooling = var.iac_tooling
5656
terraform = <<EOT
57-
version: ${lookup(data.external.iac_tooling_version.0.result, "terraform_version")}
58-
revision: ${lookup(data.external.iac_tooling_version.0.result, "terraform_revision")}
59-
provider-selections: ${lookup(data.external.iac_tooling_version.0.result, "provider_selections")}
60-
outdated: ${lookup(data.external.iac_tooling_version.0.result, "terraform_outdated")}
57+
version: ${lookup(data.external.iac_tooling_version[0].result, "terraform_version")}
58+
revision: ${lookup(data.external.iac_tooling_version[0].result, "terraform_revision")}
59+
provider-selections: ${lookup(data.external.iac_tooling_version[0].result, "provider_selections")}
60+
outdated: ${lookup(data.external.iac_tooling_version[0].result, "terraform_outdated")}
6161
EOT
6262
}
6363

@@ -121,7 +121,7 @@ module "gke" {
121121

122122
grant_registry_access = var.enable_registry_access
123123

124-
monitoring_service = var.create_gke_monitoring_service ? var.gke_monitoring_service : "none"
124+
monitoring_service = var.create_gke_monitoring_service ? var.gke_monitoring_service : "none"
125125
monitoring_enabled_components = var.create_gke_monitoring_service ? var.gke_monitoring_enabled_components : []
126126

127127
monitoring_enable_managed_prometheus = var.enable_managed_prometheus
@@ -261,7 +261,7 @@ module "postgresql" {
261261
user_deletion_policy = "ABANDON"
262262
database_deletion_policy = "ABANDON"
263263
database_version = "POSTGRES_${each.value.server_version}"
264-
database_flags = values(zipmap(concat(local.base_database_flags.*.name, each.value.database_flags.*.name), concat(local.base_database_flags, each.value.database_flags)))
264+
database_flags = values(zipmap(concat(local.base_database_flags[*].name, each.value.database_flags[*].name), concat(local.base_database_flags, each.value.database_flags)))
265265

266266
backup_configuration = {
267267
enabled = each.value.backups_enabled

modules/google_vm/outputs.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
output "private_ip" {
5-
value = google_compute_instance.google_vm.network_interface.0.network_ip
5+
value = google_compute_instance.google_vm.network_interface[0].network_ip
66
}
77

88
output "public_ip" {

modules/google_vm/variables.tf

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,34 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
variable "name" {
5-
type = string
5+
description = "Name of the VM to be created"
6+
type = string
67
}
78

89
variable "project" {
9-
type = string
10+
description = "The GCP Project to create the VM resources in"
11+
type = string
1012
}
1113

1214
variable "region" {
13-
type = string
15+
description = "The region to create the VM in"
16+
type = string
1417
}
1518

1619
variable "zone" {
17-
type = string
20+
description = "The zone to create the VM resources in"
21+
type = string
1822
}
1923

2024
variable "subnet" {
21-
type = string
25+
description = "The subnetwork to configure VM network interface with"
26+
type = string
2227
}
2328

2429
variable "create_public_ip" {
25-
default = false
30+
description = "Toggle the creation of a public IP associated with the VM"
31+
type = bool
32+
default = false
2633
}
2734

2835
variable "tags" {
@@ -32,41 +39,51 @@ variable "tags" {
3239
}
3340

3441
variable "machine_type" {
35-
default = "n2-standard-4"
42+
description = "Machine type of the VM to be created"
43+
type = string
44+
default = "n2-standard-4"
3645
}
3746

3847
variable "user_data" {
39-
default = ""
40-
}
41-
42-
variable "user_data_type" {
43-
default = "" # "cloud-config" "startup-script"
48+
description = "Script to be run on the VM during provision time"
49+
type = string
50+
default = ""
4451
}
4552

4653
variable "vm_admin" {
4754
description = "Login account for VM"
55+
type = string
4856
default = "googleuser"
4957
}
5058

5159
variable "ssh_public_key" {
5260
description = "Path to ssh public key"
61+
type = string
5362
default = null
5463
}
5564

5665
variable "os_image" {
57-
default = "ubuntu-os-cloud/ubuntu-2004-lts" # FAMILY/PROJECT glcoud compute images list
66+
description = "OS Image to configure the VM with"
67+
type = string
68+
default = "ubuntu-os-cloud/ubuntu-2004-lts" # FAMILY/PROJECT glcoud compute images list
5869
}
5970

6071

6172
variable "data_disk_count" {
62-
default = 0
73+
description = "Number of compute disks to associated with the VM"
74+
type = number
75+
default = 0
6376
}
6477

6578
variable "data_disk_size" {
66-
default = 128
79+
description = "Size of the compute disks associated with the VM"
80+
type = number
81+
default = 128
6782
}
6883

6984
variable "data_disk_type" {
70-
default = "pd-ssd"
85+
description = "Type of compute disk to associate with the VM"
86+
type = string
87+
default = "pd-ssd"
7188
}
7289

0 commit comments

Comments
 (0)