Skip to content

Commit 69e2e58

Browse files
authored
Merge pull request #104 from maddevsio/tfsec
use tfsec for static analysing terraform code
2 parents 857d511 + 1007abc commit 69e2e58

File tree

10 files changed

+136
-34
lines changed

10 files changed

+136
-34
lines changed

.github/workflows/terraform-ci.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ jobs:
3030
- name: Terraform Validate l2
3131
working-directory: ./terraform/layer2-k8s
3232
run: terraform validate -no-color .
33+
- name: Upload files for l1
34+
uses: actions/upload-artifact@v2
35+
with:
36+
name: l1
37+
path: ./terraform/layer1-aws/.terraform
38+
retention-days: 1
39+
- name: Upload files for l2
40+
uses: actions/upload-artifact@v2
41+
with:
42+
name: l2
43+
path: ./terraform/layer2-k8s/.terraform
44+
retention-days: 1
3345

3446
# Checks that all Terraform configuration files format
3547
terraform-format:
@@ -63,3 +75,52 @@ jobs:
6375
- name: Terraform tflint l2
6476
working-directory: ./terraform/layer2-k8s
6577
run: tflint --no-color
78+
79+
terraform-tfsec-l1:
80+
name: 'Terraform-tfsec-l1'
81+
needs: terraform-validate
82+
runs-on: ubuntu-latest
83+
container:
84+
image: tfsec/tfsec
85+
options: --user root
86+
steps:
87+
- name: Checkout
88+
uses: actions/checkout@v2
89+
- name: Download init for l1
90+
uses: actions/download-artifact@v2
91+
with:
92+
name: l1
93+
path: ./terraform/layer1-aws/.terraform
94+
- name: tfsec l1
95+
working-directory: ./terraform
96+
run: tfsec layer1-aws
97+
- uses: geekyeggo/delete-artifact@v1
98+
with:
99+
name: l1
100+
failOnError: false
101+
if: ${{ always() }}
102+
103+
terraform-tfsec-l2:
104+
name: 'Terraform-tfsec-l2'
105+
needs: terraform-validate
106+
runs-on: ubuntu-latest
107+
container:
108+
image: tfsec/tfsec
109+
options: --user root
110+
steps:
111+
- name: Checkout
112+
uses: actions/checkout@v2
113+
- name: Download init for l2
114+
uses: actions/download-artifact@v2
115+
with:
116+
name: l2
117+
path: ./terraform/layer2-k8s/.terraform
118+
- name: Terraform tfsec l2
119+
working-directory: ./terraform
120+
run: tfsec layer2-k8s
121+
- uses: geekyeggo/delete-artifact@v1
122+
with:
123+
name: l2
124+
failOnError: false
125+
if: ${{ always() }}
126+

README.md

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -42,39 +42,51 @@ You can find more about this project in Anton Babenko stream:
4242

4343
## Table of contents
4444

45-
- [Architecture diagram](#architecture-diagram)
46-
- [Current infrastructure cost](#current-infrastructure-cost)
47-
- [Namespace structure in the K8S cluster](#namespace-structure-in-the-k8s-cluster)
48-
- [Useful tools](#useful-tools)
49-
- [Useful VSCode extensions](#useful-vscode-extensions)
50-
- [AWS account](#aws-account)
51-
- [IAM settings](#iam-settings)
52-
- [Setting up awscli](#setting-up-awscli)
53-
- [How to use this repo](#how-to-use-this-repo)
54-
- [Getting ready](#getting-ready)
55-
- [S3 state backend](#s3-state-backend)
56-
- [Secrets](#secrets)
57-
- [Domain and SSL](#domain-and-ssl)
58-
- [Working with terraform](#working-with-terraform)
59-
- [init](#init)
60-
- [plan](#plan)
61-
- [apply](#apply)
62-
- [terragrunt](#terragrunt)
63-
- [What to do after deployment](#what-to-do-after-deployment)
64-
- [examples](#examples)
65-
- [Coding conventions](#coding-conventions)
66-
- [Names and approaches used in code](#names-and-approaches-used-in-code)
67-
- [Base project name](#base-project-name)
68-
- [Unique prefix of resource names](#unique-prefix-of-resource-names)
69-
- [Separators](#separators)
70-
- [Resource names](#resource-names)
71-
- [Variable names](#variable-names)
72-
- [Output names](#output-names)
73-
- [Names of terraform files, directories, and modules](#names-of-terraform-files-directories-and-modules)
74-
- [General configuration files](#general-configuration-files)
75-
- [Specific configuration files](#specific-configuration-files)
76-
- [Modules](#modules)
77-
- [Project structure](#project-structure)
45+
- [Boilerplate for a basic AWS infrastructure with EKS cluster](#boilerplate-for-a-basic-aws-infrastructure-with-eks-cluster)
46+
- [Advantages of this boilerplate](#advantages-of-this-boilerplate)
47+
- [Why you should use this boilerplate](#why-you-should-use-this-boilerplate)
48+
- [Description](#description)
49+
- [Table of contents](#table-of-contents)
50+
- [Architecture diagram](#architecture-diagram)
51+
- [Current infrastructure cost](#current-infrastructure-cost)
52+
- [Namespace structure in the K8S cluster](#namespace-structure-in-the-k8s-cluster)
53+
- [Useful tools](#useful-tools)
54+
- [Useful VSCode extensions](#useful-vscode-extensions)
55+
- [AWS account](#aws-account)
56+
- [IAM settings](#iam-settings)
57+
- [Setting up awscli](#setting-up-awscli)
58+
- [How to use this repo](#how-to-use-this-repo)
59+
- [Getting ready](#getting-ready)
60+
- [S3 state backend](#s3-state-backend)
61+
- [Inputs](#inputs)
62+
- [Secrets](#secrets)
63+
- [Domain and SSL](#domain-and-ssl)
64+
- [Working with terraform](#working-with-terraform)
65+
- [init](#init)
66+
- [plan](#plan)
67+
- [apply](#apply)
68+
- [terragrunt](#terragrunt)
69+
- [Apply infrastructure by layers with `terragrunt`](#apply-infrastructure-by-layers-with-terragrunt)
70+
- [Target apply by `terragrunt`](#target-apply-by-terragrunt)
71+
- [Destroy infrastructure by `terragrunt`](#destroy-infrastructure-by-terragrunt)
72+
- [What to do after deployment](#what-to-do-after-deployment)
73+
- [Update terraform version](#update-terraform-version)
74+
- [Updated terraform providers](#updated-terraform-providers)
75+
- [examples](#examples)
76+
- [TFSEC](#tfsec)
77+
- [Coding conventions](#coding-conventions)
78+
- [Names and approaches used in code](#names-and-approaches-used-in-code)
79+
- [Base project name](#base-project-name)
80+
- [Unique prefix of resource names](#unique-prefix-of-resource-names)
81+
- [Separators](#separators)
82+
- [Resource names](#resource-names)
83+
- [Variable names](#variable-names)
84+
- [Output names](#output-names)
85+
- [Names of terraform files, directories, and modules](#names-of-terraform-files-directories-and-modules)
86+
- [General configuration files](#general-configuration-files)
87+
- [Specific configuration files](#specific-configuration-files)
88+
- [Modules](#modules)
89+
- [Project structure](#project-structure)
7890

7991
## Architecture diagram
8092

@@ -455,6 +467,28 @@ Each layer has an `examples/` directory that contains working examples that expa
455467
456468
This will allow you to expand your basic functionality by launching a monitoring system based on ELK or Prometheus Stack, etc.
457469
470+
## TFSEC
471+
We use GitHub Actions and [tfsec](https://github.com/aquasecurity/tfsec) to check our terraform code using static analysis to spot potential security issues. However, we needed to skip some checks. The list of those checks is below:
472+
473+
| Layer | Security issue | Description | Why skipped? |
474+
|---------------|--------------------------|----------------|-----------------|
475+
| layer1-aws/aws-eks.tf | aws-vpc-no-public-egress-sgr | Resource 'module.eks:aws_security_group_rule.cluster_egress_internet[0]' defines a fully open egress security group rule. | We use recommended option. [More info](https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html) |
476+
| layer1-aws/aws-eks.tf | aws-eks-enable-control-plane-logging | Resource 'module.eks:aws_eks_cluster.this[0]' is missing the control plane log type 'scheduler' | By default we enable only audit logs. Can be changed via variable eks_cluster_enabled_log_types |
477+
| layer1-aws/aws-eks.tf | aws-eks-encrypt-secrets | Resource 'module.eks:aws_eks_cluster.this[0]' has no encryptionConfigBlock block | By default encryption is disabled, but can be enabled via setting *eks_cluster_encryption_config_enable = true* in your tfvars file. |
478+
| layer1-aws/aws-eks.tf | aws-eks-no-public-cluster-access | Resource 'module.eks:aws_eks_cluster.this[0]' has public access is explicitly set to enabled | By default we create public accessible EKS cluster from anywhere |
479+
| layer1-aws/aws-eks.tf | aws-eks-no-public-cluster-access-to-cidr | Resource 'module.eks:aws_eks_cluster.this[0]' has public access cidr explicitly set to wide open | By default we create public accessible EKS cluster from anywhere |
480+
| layer1-aws/aws-eks.tf | aws-vpc-no-public-egress-sgr | Resource 'module.eks:aws_security_group_rule.workers_egress_internet[0]' defines a fully open egress security group rule | We use recommended option. [More info](https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html) |
481+
| modules/aws-iam-ssm/iam.tf | aws-iam-no-policy-wildcards | Resource 'module.aws_iam_external_secrets:data.aws_iam_policy_document.this' defines a policy with wildcarded resources. | We use aws-iam-ssm module for external-secrets and grant it access to all secrets. |
482+
| modules/aws-iam-autoscaler/iam.tf | aws-iam-no-policy-wildcards | Resource 'module.aws_iam_autoscaler:data.aws_iam_policy_document.this' defines a policy with wildcarded resources | We use condition to allow run actions only for certain autoscaling groups |
483+
| modules/kubernetes-network-policy-namespace/main.tf | kubernetes-network-no-public-ingress | Resource 'module.dev_ns_network_policy:kubernetes_network_policy.deny-all' allows all ingress traffic by default | We deny all ingress trafic by default, but tfsec doesn't work as expected (bug) |
484+
| modules/kubernetes-network-policy-namespace/main.tf | kubernetes-network-no-public-egress | Resource 'module.dev_ns_network_policy:kubernetes_network_policy.deny-all' allows all egress traffic by default | We don't want to deny egress traffic in a default installation |
485+
| kubernetes-network-policy-namespace/main.tf | kubernetes-network-no-public-egress | Resource 'module.dev_ns_network_policy:kubernetes_network_policy.allow-from-this' allows all egress traffic by default | We don't want to deny egress traffic in a default installation |
486+
| modules/kubernetes-network-policy-namespace/main.tf | kubernetes-network-no-public-egress | Resource 'module.dev_ns_network_policy:kubernetes_network_policy.allow-from-ns[0]' allows all egress traffic by default | We don't want to deny egress traffic in a default installation |
487+
| modules/aws-iam-aws-loadbalancer-controller/iam.tf | aws-iam-no-policy-wildcards | Resource 'module.eks_alb_ingress[0]:module.aws_iam_aws_loadbalancer_controller:aws_iam_role_policy.this' defines a policy with wildcarded resources | We use recommended [policy](https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json) |
488+
| layer2-k8s/locals.tf | general-secrets-sensitive-in-local | Local 'locals.' includes a potentially sensitive value which is defined within the project | tfsec complains on helm_repo_external_secrets url because it contains the word *secret* |
489+
| modules/aws-iam-external-dns/main.tf | aws-iam-no-policy-wildcards | Resource 'module.aws_iam_external_dns:aws_iam_role_policy.this' defines a policy with wildcarded resources | We use the policy from the [documentation](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md#iam-policy)
490+
| modules/aws-iam-external-dns/main.tf | aws-iam-no-policy-wildcards | Resource 'module.aws_iam_cert_manager:aws_iam_role_policy.this' defines a policy with wildcarded resources | Certmanager uses Route53 to create DNS records and validate wildcard certificates. By default we allow it to manage all zones |
491+
458492
## Coding conventions
459493
460494
This section contains the most basic recommendations for users and contributors on coding, naming, etc. The goal is consistent, standardized, readable code. Additions, suggestions and changes are welcome.

terraform/layer1-aws/aws-eks.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ locals {
2323
]
2424
}
2525

26+
#tfsec:ignore:aws-vpc-no-public-egress-sgr tfsec:ignore:aws-eks-enable-control-plane-logging tfsec:ignore:aws-eks-encrypt-secrets tfsec:ignore:aws-eks-no-public-cluster-access tfsec:ignore:aws-eks-no-public-cluster-access-to-cidr
2627
module "eks" {
2728
source = "terraform-aws-modules/eks/aws"
2829
version = "17.1.0"

terraform/layer2-k8s/eks-aws-loadbalancer-controller.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#tfsec:ignore:aws-iam-no-policy-wildcards
12
module "eks_alb_ingress" {
23
source = "../modules/eks-aws-loadbalancer-controller"
34
count = var.aws_loadbalancer_controller_enable ? 1 : 0

terraform/layer2-k8s/eks-cert-manager.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#tfsec:ignore:aws-iam-no-policy-wildcards
12
module "aws_iam_cert_manager" {
23
source = "../modules/aws-iam-external-dns"
34

terraform/layer2-k8s/eks-cluster-autoscaler.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#tfsec:ignore:aws-iam-no-policy-wildcards
12
module "aws_iam_autoscaler" {
23
source = "../modules/aws-iam-autoscaler"
34

terraform/layer2-k8s/eks-external-dns.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#tfsec:ignore:aws-iam-no-policy-wildcards
12
module "aws_iam_external_dns" {
23
source = "../modules/aws-iam-external-dns"
34

terraform/layer2-k8s/eks-external-secrets.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#tfsec:ignore:aws-iam-no-policy-wildcards
12
module "aws_iam_external_secrets" {
23
source = "../modules/aws-iam-ssm"
34

terraform/layer2-k8s/eks-network-policy.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ resource "helm_release" "calico_daemonset" {
1616
]
1717
}
1818

19+
#tfsec:ignore:kubernetes-network-no-public-egress tfsec:ignore:kubernetes-network-no-public-ingress
1920
module "dev_ns_network_policy" {
2021
source = "../modules/kubernetes-network-policy-namespace"
2122
namespace = kubernetes_namespace.dev.metadata[0].name

terraform/layer2-k8s/locals.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ locals {
2222
helm_repo_eks = "https://aws.github.io/eks-charts"
2323
helm_repo_softonic = "https://charts.softonic.io"
2424
helm_repo_elastic = "https://helm.elastic.co"
25-
helm_repo_external_secrets = "https://external-secrets.github.io/kubernetes-external-secrets"
25+
helm_repo_external_secrets = "https://external-secrets.github.io/kubernetes-external-secrets" #tfsec:ignore:general-secrets-sensitive-in-local
2626
helm_repo_stakater = "https://stakater.github.io/stakater-charts"
2727
helm_repo_cluster_autoscaler = "https://kubernetes.github.io/autoscaler"
2828
helm_repo_ingress_nginx = "https://kubernetes.github.io/ingress-nginx"

0 commit comments

Comments
 (0)