├── .dockerignore
├── .drone.yml
├── .gitignore
├── .gitmodules
├── .terraform-docs.yml
├── .terraformignore
├── Dockerfile
├── LICENSE
├── README.md
├── Taskfile.yml
├── assets
└── .gitkeep
├── config
├── aws-filter.yaml
└── gcp-filter.yaml
├── docs
├── .dockerignore
├── Dockerfile
├── build.yml
├── build
│ └── .gitkeep
├── docker-compose.yml
├── md
│ ├── 404.md
│ ├── _toc.md
│ ├── docs
│ │ ├── code-features.md
│ │ ├── development
│ │ │ ├── contact.md
│ │ │ ├── contributions.md
│ │ │ ├── guidelines.md
│ │ │ ├── prs.md
│ │ │ ├── roadmap.md
│ │ │ └── tests.md
│ │ ├── intro
│ │ │ ├── about.md
│ │ │ ├── legal.md
│ │ │ ├── next-steps.md
│ │ │ ├── terms.md
│ │ │ ├── thanks.md
│ │ │ └── what-is.md
│ │ ├── providers
│ │ │ ├── amnzaws.md
│ │ │ ├── gcloud.md
│ │ │ ├── msazure.md
│ │ │ └── oracle.md
│ │ └── setup
│ │ │ ├── environment.md
│ │ │ ├── first-run.md
│ │ │ ├── getting-started.md
│ │ │ ├── installing.md
│ │ │ ├── management.md
│ │ │ ├── requirements.md
│ │ │ └── resources.md
│ └── index.md
└── vercel.json
├── examples
├── aws
│ ├── e2e
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ └── unit
│ │ ├── ec2
│ │ ├── README.md
│ │ ├── main.tf
│ │ └── variables.tf
│ │ └── rds
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
├── azure
│ ├── e2e
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ └── unit
│ │ ├── compute
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ │ └── db
│ │ ├── main.tf
│ │ └── variables.tf
└── gcp
│ ├── e2e
│ ├── README.md
│ ├── main.tf
│ ├── terraform.tfvars.example
│ └── variables.tf
│ └── unit
│ ├── compute
│ ├── README.md
│ ├── main.tf
│ ├── terraform.tfvars.example
│ └── variables.tf
│ ├── storage
│ ├── README.md
│ ├── main.tf
│ ├── terraform.tfvars.example
│ └── variables.tf
│ └── vpc
│ ├── README.md
│ ├── main.tf
│ ├── terraform.tfvars.example
│ └── variables.tf
├── main.tf
├── modules
├── aws
│ ├── README.md
│ ├── ec2
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── firewall
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── gateway
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── rds
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── variables.tf
│ └── vpc
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
├── azure
│ ├── README.md
│ ├── compute
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── db
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── vpc
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
└── gcp
│ ├── README.md
│ ├── compute
│ ├── README.md
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
│ ├── firewall
│ ├── README.md
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── storage
│ ├── README.md
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
│ ├── variables.tf
│ └── vpc
│ ├── README.md
│ ├── main.tf
│ └── variables.tf
├── outputs.tf
├── renovate.json
├── scripts
├── entrypoint.sh
├── plan.sh
├── requirements.txt
├── slim.yml
└── test.sh
├── tasks
├── aws.yaml
├── clean.yaml
├── docker.yaml
└── gcp.yaml
├── test
├── aws
│ ├── README.md
│ ├── ec2_test.go
│ ├── network_test.go
│ └── rds_test.go
├── azure
│ └── azure_integrated_test.go
├── docker
│ └── dockerfile_test.go
└── gcp
│ ├── compute_test.go
│ ├── gcp_test.go
│ ├── storage_test.go
│ └── vpc_test.go
├── variables.tf
└── versions.tf
/.dockerignore:
--------------------------------------------------------------------------------
1 | # Local .terraform directories
2 | **/.terraform/*
3 | *.tfstate
4 | *.tfstate.*
5 | crash.log
6 | override.tf
7 | override.tf.json
8 | *_override.tf
9 | *_override.tf.json
10 | **/.terraform.lock.hcl/*
11 | .terraform.lock.hcl
12 | .terraform
13 | *tfplan*
14 | terraform.tfvars
15 | graph.json
16 | graph.svg
17 | *.tfvars
18 | terraform.tfvars
19 | terraform.env.tfvars
20 | *.tfstate.*
21 | graph.png
22 | plan.json
23 | plan.out
24 | graph.html
25 | index.html
26 |
27 | # credentials
28 | aws.json
29 | aws.pub
30 | **/gcp.json/*
31 | gcp.json
32 | *.pub
33 | **/id_rsa.pub/*
34 | id_rsa.*
35 | **/id_rsa/*
36 |
37 | # Documentation / Node.js
38 | docs/dist/*
39 | docs/*.html
40 | */*.html
41 | *.html
42 | logs
43 | *.log
44 | *.js
45 | *.meta.json
46 | *.css
47 | npm-debug.log*
48 | yarn-debug.log*
49 | yarn-error.log*
50 | lerna-debug.log*
51 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
52 | pids
53 | *.pid
54 | *.seed
55 | *.pid.lock
56 | lib-cov
57 | coverage
58 | *.lcov
59 | .nyc_output
60 | .grunt
61 | bower_components
62 | .lock-wscript
63 | build/Release
64 | node_modules/
65 | jspm_packages/
66 | typings/
67 | *.tsbuildinfo
68 | .npm
69 | .eslintcache
70 | .rpt2_cache/
71 | .rts2_cache_cjs/
72 | .rts2_cache_es/
73 | .rts2_cache_umd/
74 | .node_repl_history
75 | *.tgz
76 | .yarn-integrity
77 | .env
78 | .env.test
79 | .cache
80 | index.html
81 | .next
82 | .nuxt
83 | dist
84 | .cache/
85 | .vuepress/dist
86 | .serverless/
87 | .fusebox/
88 | .dynamodb/
89 | .tern-por
90 | *.json
91 | *.lock.hcl
92 |
93 | # .vscode
94 | .vscode
95 |
96 | # Artifacts docker-slim
97 | slim.report.json
98 | Dockerfile.fat
99 | creport.jsondiff
100 | *.report.json
101 |
102 | # Terraform Visual
103 | terraform-visual-report
104 | terraform-visual-report/*
105 |
106 | # Blast Radius
107 | blast/*
108 | blast
--------------------------------------------------------------------------------
/.drone.yml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: pipeline
3 | type: docker
4 | name: Basic testing
5 | trigger:
6 | event:
7 | include:
8 | - push
9 | exclude:
10 | - pull_request
11 |
12 | node:
13 | server: home
14 | arm: no
15 | docker: yes
16 | platform:
17 | os: linux
18 | arch: amd64
19 |
20 | steps:
21 | - name: Build Image
22 | image: plugins/docker
23 | settings:
24 | dockerfile: Dockerfile
25 | pull_images: true
26 | repo: ghcr.io/gruberdev/freetf
27 | cache_from: ghcr.io/gruberdev/freetf
28 | registry: ghcr.io
29 | username: gruberdev
30 | password:
31 | from_secret: gh_token
32 |
33 | - name: Terraform Plan
34 | image: ghcr.io/gruberdev/freetf:latest
35 | commands:
36 | - mkdir -p ~/.ssh-temp
37 | - chmod 700 ~/.ssh-temp
38 | - ssh-keygen -t rsa -b 4096 -C "example@gmail.com" -N 'test' -f ~/.ssh-temp/id_rsa
39 | - touch key.json && echo $$GOOGLE_CREDENTIALS >> key.json
40 | - export GOOGLE_APPLICATION_CREDENTIAL=key.json
41 | - terraform init -upgrade -reconfigure -force-copy
42 | - terraform plan
43 | environment:
44 | ARM_CLIENT_ID:
45 | from_secret: arm_id
46 | ARM_CLIENT_CERTIFICATE_PATH:
47 | from secret: azure_path
48 | ARM_CLIENT_CERTIFICATE_PASSWORD:
49 | from_secret: cte_password
50 | ARM_SUBSCRIPTION_ID:
51 | from_secret: azure_sub_id
52 | ARM_TENANT_ID:
53 | from_secret: azure_tenant_id
54 | GOOGLE_CREDENTIALS:
55 | from_secret: gcp_json
56 | GOOGLE_PROJECT:
57 | from_secret: google_cloud_projectid
58 | AWS_DEFAULT_REGION:
59 | from_secret: aws_default_region
60 | AWS_SECRET_ACCESS_KEY:
61 | from_secret: aws_account_secret
62 | AWS_ACCESS_KEY_ID:
63 | from_secret: aws_account_id
64 | depends_on:
65 | - Build Image
66 |
67 | - name: Finished testing
68 | image: ghcr.io/gruberdev/freetf:latest
69 | commands:
70 | - echo "Finished basic setup!"
71 | depends_on:
72 | - Terraform Plan
73 | - Build Image
74 |
75 | # - name: tfsec
76 | # image: tfsec/tfsec
77 | # commands:
78 | # - tfsec . -e GCP003,AWS044,GEN003
79 | # when:
80 | # status:
81 | # - success
82 | # - failure
83 | # event:
84 | # - push
85 | # - pull_request
86 | # environment:
87 | # GOOGLE_PROJECT:
88 | # from_secret: gcp_project_id
89 | # GOOGLE_KEY:
90 | # from_secret: gcp_default
91 | # AWS_DEFAULT_REGION:
92 | # from_secret: aws_region
93 | # AWS_SECRET_ACCESS_KEY:
94 | # from_secret: aws_key
95 | # AWS_ACCESS_KEY_ID:
96 | # from_secret: aws_id
97 | # - name: terrascan
98 | # image: accurics/terrascan
99 | # commands:
100 | # - terrascan scan
101 | # when:
102 | # status:
103 | # - success
104 | # - failure
105 | # event:
106 | # - push
107 | # - pull_request
108 | # - rollback
109 | # environment:
110 | # GOOGLE_PROJECT:
111 | # from_secret: gcp_project_id
112 | # GOOGLE_KEY:
113 | # from_secret: gcp_default
114 | # AWS_DEFAULT_REGION:
115 | # from_secret: aws_region
116 | # AWS_SECRET_ACCESS_KEY:
117 | # from_secret: aws_key
118 | # AWS_ACCESS_KEY_ID:
119 | # from_secret: aws_id
120 | # ---
121 | # kind: pipeline
122 | # type: docker
123 | # name: Amazon Web Services (AWS)
124 | # platform:
125 | # arch: amd64
126 | # depends_on:
127 | # - Basic testing
128 | # - Kickoff
129 | # trigger:
130 | # exclude:
131 | # - pull_request
132 | # include:
133 | # - push
134 | # branch:
135 | # exclude:
136 | # - renovate/*
137 | # include:
138 | # - main
139 | # - feature/aws_*
140 | # steps:
141 | # - name: Setup AWS
142 | # image: golang:1.16.6-alpine
143 | # commands:
144 | # - apk update && apk add curl && sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
145 | # - task init-drone
146 | # - task aws-init
147 | # environment:
148 | # AWS_DEFAULT_REGION:
149 | # from_secret: aws_region
150 | # AWS_SECRET_ACCESS_KEY:
151 | # from_secret: aws_key
152 | # AWS_ACCESS_KEY_ID:
153 | # from_secret: aws_id
154 | # - name: Unit Test EC2
155 | # image: golang:1.16.6-alpine
156 | # commands:
157 | # - apk update && apk add curl && sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
158 | # - task init-drone
159 | # - task unit-ec2-aws
160 | # depends_on:
161 | # - Setup AWS
162 | # environment:
163 | # AWS_DEFAULT_REGION:
164 | # from_secret: aws_region
165 | # AWS_SECRET_ACCESS_KEY:
166 | # from_secret: aws_key
167 | # AWS_ACCESS_KEY_ID:
168 | # from_secret: aws_id
169 | # - name: Unit Test RDS
170 | # image: golang:1.16.6-alpine
171 | # commands:
172 | # - apk update && apk add curl && sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
173 | # - task init-drone
174 | # - task unit-rds-aws
175 | # depends_on:
176 | # - Setup AWS
177 | # - Unit Test EC2
178 | # environment:
179 | # AWS_DEFAULT_REGION:
180 | # from_secret: aws_region
181 | # AWS_SECRET_ACCESS_KEY:
182 | # from_secret: aws_key
183 | # AWS_ACCESS_KEY_ID:
184 | # from_secret: aws_id
185 | # ---
186 | # kind: pipeline
187 | # type: docker
188 | # name: Google Cloud Provider (GCP)
189 | # platform:
190 | # arch: amd64
191 | # depends_on:
192 | # - Basic testing
193 | # - Kickoff
194 | # trigger:
195 | # exclude:
196 | # - pull_request
197 | # include:
198 | # - push
199 | # branch:
200 | # exclude:
201 | # - renovate/*
202 | # include:
203 | # - main
204 | # - feature/gcp_*
205 | # steps:
206 | # - name: Setup
207 | # image: golang:1.16.6-alpine
208 | # commands:
209 | # - apk update && apk add curl && sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
210 | # - task init-drone
211 | # environment:
212 | # GOOGLE_CREDENTIALS:
213 | # from_secret: gcp_key
214 | # GOOGLE_PROJECT:
215 | # from_secret: gcp_project_id
216 |
217 | # - name: GCP Start Notification
218 | # image: appleboy/drone-discord
219 | # settings:
220 | # webhook_id:
221 | # from_secret: discord_id
222 | # webhook_token:
223 | # from_secret: discord_token
224 | # message: |-
225 | # Started GCP Pipeline on Drone CI.
226 | # Build number: {{build.number}}
227 |
228 | # - name: Unit Compute
229 | # image: golang:1.16.6-alpine
230 | # commands:
231 | # - apk update && apk add curl && sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
232 | # - task init-drone
233 | # - task unit-compute-gcp
234 | # depends_on:
235 | # - Setup
236 | # environment:
237 | # GOOGLE_CREDENTIALS:
238 | # from_secret: gcp_key
239 | # GOOGLE_PROJECT:
240 | # from_secret: gcp_project_id
241 |
242 | # - name: Unit Networking
243 | # image: golang:1.16.6-alpine
244 | # commands:
245 | # - apk update && apk add curl && sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
246 | # - task init-drone
247 | # - task unit-network-gcp
248 | # depends_on:
249 | # - Setup
250 | # environment:
251 | # GOOGLE_CREDENTIALS:
252 | # from_secret: gcp_key
253 | # GOOGLE_PROJECT:
254 | # from_secret: gcp_project_id
255 |
256 | # # - name: Unit Bucket Storage
257 | # # image: golang:1.16.5-alpine
258 | # # commands:
259 | # # - apk update && apk add curl && sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
260 | # # - task init-drone
261 | # # - task unit-storage-gcp
262 | # # depends_on:
263 | # # - Setup
264 | # # - Unit Networking
265 | # # - Unit Compute
266 | # # environment:
267 | # # GOOGLE_CREDENTIALS:
268 | # # from_secret: gcp_key
269 | # # GOOGLE_PROJECT:
270 | # # from_secret: gcp_project_id
271 |
272 | # - name: Testing has been sucessful
273 | # image: golang:1.16.6-alpine
274 | # commands:
275 | # - echo "Finished."
276 | # depends_on:
277 | # - Unit Networking
278 | # - Unit Compute
279 | # - Setup
280 | # environment:
281 | # GOOGLE_CREDENTIALS:
282 | # from_secret: gcp_key
283 | # GOOGLE_PROJECT:
284 | # from_secret: gcp_project_id
285 |
286 | # ---
287 | # kind: pipeline
288 | # type: docker
289 | # name: Success Webhook Notification
290 | # platform:
291 | # arch: amd64
292 | # depends_on:
293 | # - Basic testing
294 | # - Kickoff
295 | # - Google Cloud Provider (GCP)
296 | # - Amazon Web Services (AWS)
297 | # trigger:
298 | # event:
299 | # include:
300 | # - push
301 | # exclude:
302 | # - pull_request
303 | # status:
304 | # - success
305 | # steps:
306 | # - name: Notification Webhook
307 | # image: appleboy/drone-discord
308 | # settings:
309 | # webhook_id:
310 | # from_secret: discord_id
311 | # webhook_token:
312 | # from_secret: discord_token
313 | # message: |-
314 | # Pipeline {{build.number}} has been sucessfully completed.
315 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local .terraform directories
2 | **/.terraform/*
3 | *.tfstate
4 | *.tfstate.*
5 | crash.log
6 | override.tf
7 | override.tf.json
8 | *_override.tf
9 | *_override.tf.json
10 | **/.terraform.lock.hcl/*
11 | .terraform.lock.hcl
12 | .terraform
13 | *tfplan*
14 | graph.json
15 | graph.svg
16 | *.tfvars
17 | terraform.tfvars
18 | terraform.env.tfvars
19 | *.tfstate.*
20 | graph.png
21 | plan.json
22 | plan.out
23 | graph.html
24 | index.html
25 | backend.tf
26 |
27 | # Terraform Backend
28 | .terraform.tfstate.lock.info
29 |
30 | # Go project-related
31 | test/*/go.sum
32 | test/*/go.mod
33 | test/gcp/go.mod
34 | test/gcp/go.sum
35 | test/aws/go.sum
36 | test/aws/go.mod
37 | test/go.mod
38 | test/go.sum
39 | test/docker/go.mod
40 | test/docker/go.sum
41 |
42 | # credentials
43 | aws.json
44 | aws.pub
45 | **/gcp.json/*
46 | gcp.json
47 | *.pub
48 | **/id_rsa.pub/*
49 | id_rsa.*
50 | **/id_rsa/*
51 |
52 | # Documentation / Node.js
53 | docs/dist/*
54 | docs/*.html
55 | */*.html
56 | *.html
57 | *.json
58 | logs
59 | *.log
60 | *.js
61 | *.meta.json
62 | *.css
63 | npm-debug.log*
64 | yarn-debug.log*
65 | yarn-error.log*
66 | lerna-debug.log*
67 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
68 | pids
69 | *.pid
70 | *.seed
71 | *.pid.lock
72 | lib-cov
73 | coverage
74 | *.lcov
75 | .nyc_output
76 | .grunt
77 | bower_components
78 | .lock-wscript
79 | build/Release
80 | node_modules/
81 | jspm_packages/
82 | typings/
83 | *.tsbuildinfo
84 | .npm
85 | .eslintcache
86 | .rpt2_cache/
87 | .rts2_cache_cjs/
88 | .rts2_cache_es/
89 | .rts2_cache_umd/
90 | .node_repl_history
91 | *.tgz
92 | .yarn-integrity
93 | .env
94 | .env.test
95 | .cache
96 | index.html
97 | .next
98 | .nuxt
99 | dist
100 | .cache/
101 | .vuepress/dist
102 | .serverless/
103 | .fusebox/
104 | .dynamodb/
105 | .tern-port
106 | docs/.public/*
107 |
108 | # Docker
109 |
110 | # .vscode
111 | .vscode
112 |
113 | # Artifacts docker-slim
114 | slim.report.json
115 | Dockerfile.fat
116 | creport.jsondiff
117 | *.report.json
118 |
119 | # Terraform Visual
120 | terraform-visual-report
121 | terraform-visual-report/*
122 |
123 | # Blast Radius
124 | blast/*
125 | blast
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "setup"]
2 | path = setup
3 | url = https://github.com/gruberdev/setup
4 |
--------------------------------------------------------------------------------
/.terraform-docs.yml:
--------------------------------------------------------------------------------
1 | formatter: markdown
2 |
3 | sections:
4 | show:
5 | - inputs
6 | - outputs
7 | - modules
8 |
9 | output:
10 | file: README.md
11 | mode: inject
12 | template: |-
13 |
14 | {{ .Content }}
15 |
16 |
17 | sort:
18 | enabled: true
19 | by: name
20 |
21 | settings:
22 | anchor: false
23 | indent: 3
24 | color: true
25 | html: true
26 | escape: true
27 | default: true
28 | required: false
29 | type: true
30 | sensitive: true
31 |
--------------------------------------------------------------------------------
/.terraformignore:
--------------------------------------------------------------------------------
1 | # Misc
2 | .DS_Store
3 | LICENSE.md
4 | README.md
5 |
6 | # Binaries
7 | .terraform/
8 | *.exe
9 | *.tfstate
10 | *.backup
11 | *.bak
12 | *.info
13 |
14 | # Credentials
15 | *account.json
16 | sshkey*
17 | privkey*
18 | pubkey*
19 | id_rsa*
20 | .git/
21 | .github/
22 | .terraform/
23 | .vscode/
24 | doc/
25 | dockerfiles/
26 | kubernetes/
27 | schemas/
28 | templates/
29 | tools/backend
30 | frontend
31 | .editorconfig
32 | .gitignore
33 |
34 | # Terraform
35 | **.terraform/
36 | **.terraform.lock.hcl
37 | **.json
38 | *.json
39 |
40 | # Sensitive
41 | **policy_documents/
42 | **trust_document/
43 |
44 | # logs
45 | terraform.log
46 |
47 | # MacOS
48 | .DS_Store
49 |
50 | #Node modules
51 | node_modules/**
52 |
53 | # Coverage reports
54 | .nyc_output/**
55 | coverage/**
56 |
57 | # Build output folder
58 | dist/**
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Core Docker Packages Versioning
2 | ARG GO_VERSION=1.19.0
3 | ARG TF_CLI_VERSION="1.2.6"
4 | ARG TFSEC_VERSION="1.13.2"
5 | ARG TFDOCS_VERSION="0.9.1"
6 |
7 | # CLIs Dockerized Providers
8 | FROM hashicorp/terraform:${TF_CLI_VERSION} as build-tf-cli
9 | FROM tfsec/tfsec-alpine:v${TFSEC_VERSION}-amd64 as build-tfsec
10 | FROM cytopia/terraform-docs:${TFDOCS_VERSION} as build-terraform-docs
11 | # hadolint ignore=DL3007
12 | FROM accurics/terrascan:latest as build-tfscan
13 |
14 | ################################################################
15 |
16 | # Base Image: Alpine & Environment Configuration
17 | FROM golang:$GO_VERSION-alpine
18 |
19 | # Image Labels for Metadata Configuration
20 | LABEL org.opencontainers.image.source = "https://github.com/gruberdev/tf-free.git"
21 |
22 | COPY --from=build-tf-cli /bin/terraform /usr/local/bin/terraform
23 | COPY --from=build-tfsec /usr/bin/tfsec /usr/local/bin/tfsec
24 | COPY --from=build-terraform-docs /usr/local/bin/terraform-docs /usr/local/bin/terraform-docs
25 | COPY --from=build-tfscan /go/bin/terrascan /usr/local/bin/tfscan
26 |
27 | # Architecture Metadata
28 | ENV ARCH=amd64
29 | ENV ARCH_86=x86_64
30 | ENV OS=linux
31 | ENV TASK_VERSION=3.14.1
32 | # hadolint ignore=SC2034
33 | RUN go env -w GOPRIVATE=github.com/gruberdev
34 | ENV \
35 | LANG="${LANG:-$LANG_DEFAULT}" \
36 | LC_ALL="${LC_ALL:-$LC_ALL_DEFAULT}" \
37 | PATH="/usr/local/go/bin:${PATH}" \
38 | GO111MODULE='on' \
39 | SHELL="/bin/bash" \
40 | HAS_ALLOW_UNSAFE=y \
41 | GOCACHE=/go
42 |
43 | # Install Python and GCC dependencies
44 | # hadolint ignore=DL3018
45 | RUN apk add --update --no-cache \
46 | bash gcc g++ git curl \
47 | zlib libffi-dev binutils \
48 | openssh-client rsync \
49 | ca-certificates musl-dev
50 |
51 | # Configuring bash instead of sh
52 | SHELL ["/bin/bash", "-eo", "pipefail", "-c"]
53 |
54 | # Go-Critic
55 | RUN curl -sSfL "https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh" | sh -s '-- -b $(go env GOPATH)/bin'
56 |
57 | # Task / makefile Alternative
58 | RUN wget -q -O /tmp/task.tar.gz https://github.com/go-task/task/releases/download/v${TASK_VERSION}/task_${OS}_${ARCH}.tar.gz && \
59 | tar -C /usr/bin/ -xvf /tmp/task.tar.gz && \
60 | rm -rf /tmp/gotty.tar.gzln
61 |
62 | RUN echo "export PATH="/go/bin:/usr/local/go/bin:${PATH}"" >> "${HOME}/.bashrc"
63 |
64 | # Bootstrapping the project
65 | WORKDIR /project
66 | COPY . .
67 | RUN chmod +x /project/scripts/entrypoint.sh
68 |
69 | # Verifying dependencies existence within Dockerfile
70 | RUN curl -sL https://git.io/_has | bash -s git tfscan \
71 | tfsec terraform-docs terraform go task bash
72 |
73 | CMD ["/bin/bash"]
74 | ENTRYPOINT ["/project/scripts/entrypoint.sh"]
75 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://free.terraform.gruber.dev.br)
2 |
3 | ![docs-img] ![drone-img]
4 |
5 | ## Objective
6 |
7 | > **Creating and managing all available resources offered by major cloud providers exclusively in free-tier plans. Using Terraform to create and manage all the resources in a simplified and centralized manner.**
8 |
9 | ## Motivation
10 |
11 | Every major cloud provider offers a free tier that allows for some kind of resource free of charge, still, learning every cloud and managing these resources can prove burdensome to most.
12 |
13 | The goal is to automate the management of these resources using Terraform as the centralizing tool. It also aims to provide resources for learning and improve your skills as a SRE/DevOps Engineer and as a Terraform user, even if you're developer that never touched cloud infrastructure, nowadays there's great value in learning these tools.
14 |
15 | ## List of free-tier resources
16 |
17 |
18 |
19 |
20 | Google Cloud Platform
21 |
22 |
23 | ---
24 |
25 | ## GCP Available Resources
26 |
27 | - **1x** [Virtual Private Cloud (VPC)][gcp-vpc-info]
28 | - **1x** [Firewall][gcp-firewall-info] attached to the VPC
29 | - **1x** [Google Compute Engine][gcp-compute-info] `f1-micro` [(1 shared vCPU - 0.2 dedicatd vCPU][gcp-shared-vcpus] - and 0.6GB of Memory) attached to the `VPC`
30 | - **1x** 5GB of [regional storage][gcp-regional-storage] on [Cloud Storage][gcp-cloud-storage]
31 | - **1x** 1GB of storage in a [Firestore NoSQL Database][gcp-firestore-storage]
32 |
33 | More information at the [provider's documentation page][tf-free-gcp-resources].
34 |
35 | ---
36 |
37 |
38 |
39 |
40 |
41 | Amazon Web Services
42 |
43 |
44 |
45 | ---
46 |
47 | ### AWS Available Resources
48 |
49 | - **2x** [Virtual Private Cloud (VPC)][aws-vpc-info]
50 | - **2x** [Sub-network][aws-sub-info] attached to the VPC
51 | - **2x** [Internet Gateway (IGW)][aws-igw-info] to provide access to the VPC
52 | - **1x** [Route Table][aws-route-info] integrating all `VPC`, `Subnet` and the `Internet Gateway (IGW)`
53 | - **1x** [EC2 Instance][aws-ec2-info] attached to the `Subnet`
54 | - **1x** [Relational Database (RDS)][aws-rds-info] of your choice (e.g. MySQL, PostgreSQL)
55 | - **1x** [S3 Storage Bucket][aws-s3-info] inside `Subnet`, configured to store the Terraform's backend state
56 | - **1x** [DynamoDB Database][aws-dynamodb-info], mainly used for preventing that running multiple instances of this Terraform chart corrupt each other.
57 |
58 | More information at the [provider's documentation page][tf-free-aws-resources].
59 |
60 | ---
61 |
62 |
63 |
64 |
65 |
66 | Microsoft Azure (has limited testing)
67 |
68 |
69 | ---
70 |
71 | ### Available Resources
72 |
73 | - **1x** [Linux Virtual machine, B1S Standard tier][azure-vm-info]
74 | - **1x** [Windows Virtual machine, B1S Standard tier][azure-vm-info]
75 | - **1x** [Cloud Storage (LRS File Storage)][azure-storage-info]
76 | - **1x** [250GB MySQL Managed Database Instance][azure-sql-free-info]
77 |
78 | More information at the [provider's documentation page][tf-free-azure-resources].
79 |
80 | ---
81 |
82 | ##
83 |
84 |
85 |
86 |
87 |
88 | Oracle Cloud (not available)
89 |
90 |
91 | ---
92 |
93 | ### Available Resources
94 |
95 | - **2x** [AMD based VM, 1/8 shared CPU and 1GB RAM][oracle-compute-info]
96 | - **2x** [Oracle NoSQL Database with 20GB][oracle-database-info]
97 | - **1x** [10GB Object Storage Capacity][oracle-storage-info]
98 |
99 | More information at the [provider's documentation page][tf-free-oracle-resources].
100 |
101 | ---
102 |
103 |
104 |
105 | ---
106 |
107 | ## [❯ Getting started][getting-started]
108 |
109 | ```bash
110 | terraform init
111 | terraform apply
112 | ```
113 |
114 | If you rather use a containerized environment:
115 |
116 | ```bash
117 | git clone https://github.com/gruberdev/tf-free.git && \
118 | cd tf-free && \
119 | docker run -v $(pwd):/project -it ghcr.io/gruberdev/freetf:latest
120 | ```
121 |
122 |
123 |
124 | Terraform Module documentation (Click to expand)
125 |
126 |
127 | ---
128 |
129 |
130 | ### Modules
131 |
132 | | Name | Source | Version |
133 | |------|--------|---------|
134 | | aws | ./modules/aws | n/a |
135 | | google\_cloud | ./modules/gcp | n/a |
136 | | terraform\_state\_backend | cloudposse/tfstate-backend/aws | 0.38.1 |
137 |
138 | ### Inputs
139 |
140 | | Name | Description | Type | Default |
141 | |------|-------------|------|---------|
142 | | aws\_default\_region | Your default region for AWS resources creation. [Available regions for Google Compute on Free Tier.](https://free.terraform.gruber.dev.br/docs/resources/providers/aws#options) | `string` | `"us-east-1"` |
143 | | backend\_destroy | Allows destroying all resourcesinside the configured S3 Remote Backend. See more at [tf-free's Backend Documentation](https://free.terraform.gruber.dev.br/docs/setup/backend) | `string` | `"false"` |
144 | | backend\_stage | Stages possible for Backend. Set for a random string. | `string` | `"test"` |
145 | | ec2\_aws | Allow for the creation of EC2 instances on AWS. | `bool` | `true` |
146 | | gcp\_instance\_name | Your VM instance name. [Naming resources convention](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"gcp-machine"` |
147 | | gcp\_project\_id | Your static IP network nameP. [Naming resources convention](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"test"` |
148 | | gcp\_project\_region | Zone location of your instance, [see the list of available regions](https://cloud.google.com/compute/docs/regions-zones#available) - [Terraform provider documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#zone) | `string` | `"us-west1"` |
149 | | gcp\_storage\_permissions | See all available values for the parameter at [Predefined ACL's on GCS Permissions](https://cloud.google.com/storage/docs/access-control/lists#predefined-acl) | `string` | `"publicread"` |
150 | | prevents\_destroy | Prevents destroying the previously provisioned S3 Remote Backend. See more at [tf-free's Backend Documentation](https://free.terraform.gruber.dev.br/docs/setup/backend) | `bool` | `true` |
151 | | rds\_aws | Allow for the creation of a PostgreSQL database on AWS | `bool` | `true` |
152 |
153 | ### Outputs
154 |
155 | | Name | Description |
156 | |------|-------------|
157 | | aws\_ec2\_ipv6\_addresses | AWS EC2 IPv6 Public Address |
158 | | aws\_ec2\_password\_data | List of Base-64 encoded encrypted password data for AWS EC2 instances |
159 | | aws\_ec2\_private\_ip | AWS EC2 assigned Private IP |
160 | | aws\_ec2\_public\_ip | AWS EC2 IPv4 Public Address |
161 | | db\_backend\_name | Name of the resulting DynamoDB created for locking state files. |
162 | | gcp\_public\_ip | GCP VM Compute IPv4 Public Address |
163 | | s3\_backend\_bucket | ID of the resulting S3 bucket created on AWS as part of the backend infrastructure |
164 | | s3\_backend\_domain | Domain name of the S3 bucket created on AWS as part of the backend infrastructure |
165 |
166 |
167 |
168 |
169 | ---
170 |
171 | ## License
172 |
173 | The MIT license grant is not for Hashicorp's trademarks, which include the logo designs. [Hashicorp reserves all trademark and copyright rights in and to all Hashicorp trademarks][disclaimer].
174 |
175 | This repository **is not** associated with any of the cloud providers or Hashicorp. Terraform®, Vault®, Hashicorp's logos and names are Hasicorp's registered Trademarks. When using Hashicorp's logos, be sure to follow their [community][guidelines] and [brand usage][brand] guidelines.
176 | Be sure to [read the terms][usage-terms] of usage to understand the responsabilities involved.
177 |
178 |
179 |
180 | [drone-img]: https://img.shields.io/drone/build/gruberdev/tf-free?server=https%3A%2F%2Fdrone.gruber.dev.br&logo=drone&labelColor=1F1F1F&logoColor=41dde8&style=flat-square&label=Drone%20CI
181 | [docs-img]: https://img.shields.io/badge/read%20available%20documentation-online?style=flat-square&logo=zeit&color=black
182 |
183 |
184 |
185 | [brand]: https://www.hashicorp.com/brand
186 | [disclaimer]: https://www.hashicorp.com/trademark-policy
187 | [guidelines]: https://www.hashicorp.com/community-guidelines
188 | [free-aws]: https://aws.amazon.com/free/?all-free-tier
189 | [free-gcp]: https://cloud.google.com/free
190 | [kis-approach]: https://en.wikipedia.org/wiki/KISS_principle
191 | [free-docs-gcp]: https://cloud.google.com/free/docs/gcp-free-tier
192 | [free-azure]: https://azure.microsoft.com/en-us/free/
193 | [azure-faq]: https://azure.microsoft.com/en-us/free/free-account-faq/
194 | [usage-terms]: https://free.terraform.gruber.dev.br/docs/resources/providers/gcp#resources
195 | [azure-full-terms]: https://azure.microsoft.com/en-us/offers/ms-azr-0044p/
196 | [aws-faq]: https://aws.amazon.com/free/free-tier-faqs/
197 | [docs-repo-url]: https://github.com/CONNECT-platform/codedoc
198 | [aws-key-info]: https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys
199 | [aws-key-create]: https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/
200 | [aws-account-create]: https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/
201 | [aws-vpc-info]: https://aws.amazon.com/vpc/?vpc-blogs.sort-by=item.additionalFields.createdDate&vpc-blogs.sort-order=desc
202 | [aws-igw-info]: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html
203 | [aws-ec2-info]: https://aws.amazon.com/ec2/
204 | [aws-s3-info]: https://aws.amazon.com/s3/
205 | [aws-rds-info]: https://aws.amazon.com/rds/
206 | [aws-sub-info]: https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html
207 | [aws-tf-provider]: https://registry.terraform.io/providers/hashicorp/aws/latest/
208 | [aws-regions]: https://aws.amazon.com/about-aws/global-infrastructure/
209 | [aws-terms]: https://aws.amazon.com/free/terms/
210 | [aws-prevent-charges]: https://aws.amazon.com/premiumsupport/knowledge-center/free-tier-charges/
211 | [aws-alarms-free]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/tracking-free-tier-usage.html#free-budget
212 | [aws-sorted-list]: https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=tier%23always-free%7Ctier%2312monthsfree&awsf.Free%20Tier%20Categories=*all
213 | [aws-dynamodb-info]: https://aws.amazon.com/dynamodb/
214 | [remote-tfstate-url]: https://github.com/cloudposse/terraform-aws-tfstate-backend
215 | [tf-free-docs-cli]: https://free.terraform.gruber.dev.br/docs/setup/installing#cli
216 | [tf-free-gcp-resources]: https://free.terraform.gruber.dev.br/docs/resources/providers/gcp#resources
217 | [tf-free-aws-resources]: https://free.terraform.gruber.dev.br/docs/resources/providers/aws#resources
218 | [tf-free-azure-resources]: https://free.terraform.gruber.dev.br/docs/resources/providers/azure#resources
219 | [guidelines]: https://www.hashicorp.com/community-guidelines
220 | [free-gcp]: https://cloud.google.com/free
221 | [free-docs-gcp]: https://cloud.google.com/free/docs/gcp-free-tier
222 | [free-tier-limits]: https://cloud.google.com/free/docs/gcp-free-tier/#free-tier-usage-limits
223 | [free-tier-restrictions]: https://cloud.google.com/free/docs/gcp-free-tier/#free-tier
224 | [google-free-docs]: https://cloud.google.com/free/docs/gcp-free-tier/
225 | [google-free-landing]: https://cloud.google.com/free
226 | [unique-gcp-docs]: https://cloud.google.com/free/docs/what-makes-google-cloud-platform-different
227 | [why-google]: https://cloud.google.com/why-google-cloud
228 | [gcp-price-list]: https://cloud.google.com/pricing/list
229 | [gcp-comparison-docs]: https://cloud.google.com/free/docs/aws-azure-gcp-service-comparison
230 | [pricing-gcp-calculator]: https://cloud.google.com/products/calculator
231 | [no-free-ip]: https://cloud.google.com/free/docs/gcp-free-tier#always-free-usage-limits
232 | [pricing-egress]: https://cloud.google.com/vpc/network-pricing#internet_egress
233 | [usage-egress-gcp]: https://cloud.google.com/vpc/network-pricing#vpc-pricing
234 | [gcp-compute-info]: https://cloud.google.com/compute/docs
235 | [gcp-shared-vcpus]: https://cloud.google.com/compute/vm-instance-pricing#cpu-bursting
236 | [gcp-cloud-storage]: https://cloud.google.com/storage
237 | [gcp-vpc-info]: https://cloud.google.com/storage
238 | [gcp-firewall-info]: https://cloud.google.com/storage
239 | [gcp-regional-storage]: https://cloud.google.com/storage/docs/storage-classes#legacy
240 | [gcp-firestore-storage]: https://cloud.google.com/firestore/docs
241 | [gcp-regions]: https://cloud.google.com/compute/docs/regions-zones
242 | [brand]: https://www.hashicorp.com/brand
243 | [disclaimer]: https://www.hashicorp.com/trademark-policy
244 | [guidelines]: https://www.hashicorp.com/community-guidelines
245 | [free-aws]: https://aws.amazon.com/free/?all-free-tier
246 | [free-gcp]: https://cloud.google.com/free
247 | [free-docs-gcp]: https://cloud.google.com/free/docs/gcp-free-tier
248 | [free-azure]: https://azure.microsoft.com/en-us/free/
249 | [azure-faq]: https://azure.microsoft.com/en-us/free/free-account-faq/
250 | [azure-full-terms]: https://azure.microsoft.com/en-us/offers/ms-azr-0044p/
251 | [aws-faq]: https://aws.amazon.com/free/free-tier-faqs/
252 | [go-color-url]: https://github.com/fatih/color
253 | [go-releaser-url]: https://github.com/goreleaser/goreleaser
254 | [go-cobra-url]: https://github.com/spf13/cobra
255 | [shell-has-url]: https://github.com/kdabir/has
256 | [go-prompt-url]: https://github.com/c-bata/go-prompt
257 | [go-task-url]: https://github.com/go-task/task
258 | [go-tfexec-url]: https://github.com/hashicorp/terraform-exec
259 | [docs-repo-url]: https://github.com/CONNECT-platform/codedoc
260 | [aws-key-info]: https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys
261 | [aws-key-create]: https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/
262 | [aws-account-create]: https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/
263 | [aws-vpc-info]: https://aws.amazon.com/vpc/?vpc-blogs.sort-by=item.additionalFields.createdDate&vpc-blogs.sort-order=desc
264 | [aws-igw-info]: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html
265 | [aws-ec2-info]: https://aws.amazon.com/ec2/
266 | [aws-s3-info]: https://aws.amazon.com/s3/
267 | [aws-rds-info]: https://aws.amazon.com/rds/
268 | [aws-route-info]: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html
269 | [aws-sub-info]: https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html
270 | [aws-tf-provider]: https://registry.terraform.io/providers/hashicorp/aws/latest/
271 | [aws-regions]: https://aws.amazon.com/about-aws/global-infrastructure/
272 | [aws-terms]: https://aws.amazon.com/free/terms/
273 | [aws-prevent-charges]: https://aws.amazon.com/premiumsupport/knowledge-center/free-tier-charges/
274 | [aws-alarms-free]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/tracking-free-tier-usage.html#free-budget
275 | [aws-sorted-list]: https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=tier%23always-free%7Ctier%2312monthsfree&awsf.Free%20Tier%20Categories=*all
276 | [aws-dynamodb-info]: https://aws.amazon.com/dynamodb/
277 | [remote-tfstate-url]: https://github.com/cloudposse/terraform-aws-tfstate-backend
278 | [azure-sql-free-info]: https://azure.microsoft.com/en-us/products/azure-sql/database/
279 | [azure-vm-info]: https://azure.microsoft.com/en-us/services/virtual-machines/
280 | [azure-storage-info]: https://azure.microsoft.com/en-us/services/storage/files/
281 | [oracle-compute-info]: https://www.oracle.com/cloud/compute/
282 | [oracle-database-info]: https://www.oracle.com/database/
283 | [oracle-storage-info]: https://www.oracle.com/cloud/storage/
284 | [tf-free-oracle-resources]: https://free.terraform.gruber.dev.br/docs/resources/providers/oracle#resources
285 | [tf-free-oracle-resources]: https://free.terraform.gruber.dev.br/docs/resources/providers/oracle#resources
286 | [project-taskfile]: https://github.com/gruberdev/tf-free/blob/main/Taskfile.yml
287 | [taskfile-website]: https://taskfile.dev
288 | [getting-started]: https://free.terraform.gruber.dev.br/docs/setup/getting-started
--------------------------------------------------------------------------------
/Taskfile.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | includes:
4 | clean: ./tasks/clean.yaml
5 | aws: ./tasks/aws.yaml
6 | gcp: ./tasks/gcp.yaml
7 |
8 | tasks:
9 | docker:oneliner:
10 | deps:
11 | - docker-init
12 | - build
13 | - docker
14 | cmds:
15 | - "Loading container..."
16 |
17 | docker:init:
18 | desc: Create and cache your Docker container
19 | cmds:
20 | - docker volume rm cache_terraform || true
21 | - docker volume rm repository_results || true
22 | - docker volume create cache_terraform || true
23 | - docker volume create repository_results || true
24 |
25 | docker:
26 | desc: Create and cache your Docker container
27 | deps:
28 | - build
29 | cmds:
30 | - docker run -it --rm --name freetf freetf:latest
31 |
32 | build:
33 | desc: Create and cache your Docker container
34 | cmds:
35 | - docker build -t ghcr.io/gruberdev/freetf:latest -t docker.io/grubertech/freetf:latest --no-cache .
36 |
37 | run:
38 | cmds:
39 | - docker run -v $(pwd):/project -it ghcr.io/gruberdev/freetf:latest /bin/sh
40 |
41 | build:all:
42 | desc: Build executable binary with GoReleaser.
43 | cmds:
44 | - goreleaser --snapshot --skip-publish --rm-dist
45 |
46 | docs:gen:
47 | preconditions:
48 | - sh: 'which terraform-docs'
49 | msg: 'terraform-docs {{.PATH_ERROR}}'
50 | desc: Build documentation using Terraform-docs and the task command
51 | cmds:
52 | - terraform-docs markdown -c .terraform-docs.yml . --output-file README.md
53 | - terraform-docs markdown -c .terraform-docs.yml ./modules/aws --output-file README.md --header-from "header.md"
54 | - terraform-docs markdown -c .terraform-docs.yml ./modules/aws/ec2 --output-file README.md
55 | - terraform-docs markdown -c .terraform-docs.yml ./modules/aws/vpc --output-file README.md
56 | - terraform-docs markdown -c .terraform-docs.yml ./modules/aws/rds --output-file README.md
57 | - terraform-docs markdown -c .terraform-docs.yml ./modules/gcp --output-file README.md
58 | - terraform-docs markdown -c .terraform-docs.yml ./modules/gcp/compute --output-file README.md
59 | - terraform-docs markdown -c .terraform-docs.yml ./modules/gcp/firewall --output-file README.md
60 | - terraform-docs markdown -c .terraform-docs.yml ./modules/gcp/vpc --output-file README.md
61 | - terraform-docs markdown -c .terraform-docs.yml ./modules/azure --output-file README.md
62 | - terraform-docs markdown -c .terraform-docs.yml ./modules/azure/compute --output-file README.md
63 | - terraform-docs markdown -c .terraform-docs.yml ./modules/azure/db --output-file README.md
64 | - terraform-docs markdown -c .terraform-docs.yml ./modules/azure/vpc --output-file README.md
65 | - terraform-docs markdown -c .terraform-docs.yml ./modules/gcp/storage --output-file README.md
66 | - terraform-docs markdown -c .terraform-docs.yml ./examples/aws/e2e --output-file README.md
67 | - terraform-docs markdown -c .terraform-docs.yml ./examples/aws/unit/rds --output-file README.md
68 | - terraform-docs markdown -c .terraform-docs.yml ./examples/aws/unit/ec2 --output-file README.md
69 |
70 | docs:
71 | desc: Initialize module and build cache, and remake go.sum file on root directory.
72 | deps:
73 | - stop-docs
74 | cmds:
75 | - cd docs && docker build -t tf-free:docs .
76 | - cd docs && docker-compose up --build -d
77 |
78 | docs-deploy:
79 | desc: Initialize module and build cache, and remake go.sum file on root directory.
80 | deps:
81 | - stop-docs
82 | cmds:
83 | - cd docs && docker build -t tf-free:docs .
84 | - cd docs && docker-compose -f build.yml up --build
85 | - cd docs && rm -rf .public || true
86 | - cd docs && mkdir .public
87 | - cp -r docs/build/* docs/.public/
88 | - cp docs/vercel.json docs/.public/
89 |
90 | stop-docs:
91 | cmds:
92 | - cd docs && docker-compose down || true
93 | - cd docs && docker-compose -f build.yml down || true
94 |
95 | lint:
96 | desc: Linter built on Docker.
97 | cmds:
98 | - go mod verify
99 | - docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.40.1 golangci-lint run --enable gosec --timeout 3m0s ./...
100 | sources:
101 | - ./go.mod
102 | - "**/*.go"
103 |
104 | graph:
105 | desc: Create beautiful Terraform Graphs
106 | cmds:
107 | - go get github.com/pcasteran/terraform-graph-beautifier
108 | - terraform graph | terraform-graph-beautifier --exclude="module.root.provider" --output-type=cyto-html > graph.html
109 |
110 | full:test:local:
111 | desc: Terraform testing all providers.
112 | deps:
113 | - gcp-test
114 | - aws-test
115 | - docker-test
116 | cmds:
117 | - echo "Finished testing."
118 |
119 | apply:local:
120 | desc: Terraform standard local apply command
121 | cmds:
122 | - terraform init
123 | - terraform apply -auto-approve
124 |
125 | destroy:local:
126 | desc: Terraform standard local destroy command
127 | cmds:
128 | - terraform destroy -auto-approve
129 |
130 | init:
131 | desc: Terraform standard local init command
132 | cmds:
133 | - terraform init -upgrade
134 |
135 | init:apply:
136 | desc: Terraform standard initial apply command (w/ Backend)
137 | cmds:
138 | - terraform init -reconfigure
139 | - terraform apply -auto-approve
140 | - terraform init -force-copy
141 |
142 | init:docker:
143 | cmds:
144 | - cd test/docker && rm go.mod || true
145 | - cd test/docker && rm go.sum || true
146 | - cd test/docker && go mod init "github.com/gruberdev/tf-free" && go mod tidy
147 |
148 | docker:test:
149 | desc: Terraform standard initialization
150 | deps:
151 | - init-docker
152 | cmds:
153 | - cd test/docker && go test -v -timeout 45m -run TestDockerBuild
154 |
155 | lastdestroy:
156 | desc: Terraform standard initialization
157 | cmds:
158 | - terraform apply -var backend_destroy=true -var prevents_destroy=false -target module.terraform_state_backend -auto-approve
159 | - terraform init -force-copy
160 | - terraform destroy -target module.aws.module.rds.aws_db_instance.rds -auto-approve
161 | - terraform destroy -auto-approve
162 |
163 | docker:lint:
164 | desc: Terraform standard initialization
165 | cmds:
166 | - docker run --rm -i hadolint/hadolint < Dockerfile || true
167 |
168 | backend:enable:
169 | desc: How to transfer the backend to S3 (Remote)
170 | cmds:
171 | - terraform init -force-copy
172 |
173 | backend:disable:
174 | desc: How to destroy the backend stored in S3
175 | cmds:
176 | - terraform apply -target module.terraform_state_backend -auto-approve
177 | - terraform init -force-copy
178 |
179 | destroy:aws:
180 | desc: Terraform standard initialization
181 | cmds:
182 | - cd modules/aws && terraform destroy -auto-approve
183 |
184 | restart-aws:
185 | desc: Terraform standard initialization
186 | cmds:
187 | - cd modules/aws && terraform destroy -auto-approve
188 | - cd modules/aws && terraform apply -auto-approve
189 |
190 | heavy:artillery:
191 | desc: Destroy all resources but the S3 Backend and the DynamoDB instances on AWS.
192 | cmds:
193 | - terraform destroy -target module.google_cloud -auto-approve
194 | - terraform destroy -target module.aws -auto-approve
195 |
196 | tf:clean:
197 | desc: Terraform standard initialization
198 | cmds:
199 | - rm -rf ./.terraform || true
200 | - rm -rf ./.blast || true
201 | - rm terraform.tfstate || true
202 | - rm terraform.tfstate.backup || true
203 | - rm ./.terraform.lock.hcl || true
204 | - rm backend.tf || true
205 | - rm errored.tfstate || true
206 | - rm graph.html || true
207 | - rm index.html || true
208 | - rm plan.json || true
209 | - rm plan.out || true
210 | - rm gcp.json || true
211 | - cd modules && cd gcp && rm -rf ./.terraform && rm ./.terraform.lock.hcl || true
212 | - cd modules && cd gcp && cd vpc && rm -rf ./.terraform && rm ./.terraform.lock.hcl || true
213 | - cd modules && cd gcp && cd firewall && rm -rf ./.terraform && rm ./.terraform.lock.hcl || true
214 | - cd modules && cd gcp && cd compute && rm -rf ./.terraform && rm ./.terraform.lock.hcl || true
215 | - cd modules && cd aws && rm -rf ./.terraform && rm ./.terraform.lock.hcl || true
216 | - cd modules && cd aws && cd ec2 && rm -rf ./.terraform && rm ./.terraform.lock.hcl || true
217 | - cd modules && cd aws && cd rds && rm -rf ./.terraform && rm ./.terraform.lock.hcl || true
218 | - rm examples/aws/unit/ec2/.terraform.lock.hcl || true
219 | - rm -rf examples/aws/unit/ec2/.terraform || true
220 | - rm examples/aws/unit/ec2/terraform.tfstate || true
221 | - rm examples/aws/unit/ec2/terraform.tfstate.backup || true
222 | - rm examples/aws/unit/rds/.terraform.lock.hcl || true
223 | - rm -rf examples/aws/unit/rds/.terraform || true
224 | - rm examples/aws/unit/rds/terraform.tfstate || true
225 | - rm examples/aws/unit/rds/terraform.tfstate.backup || true
226 |
227 | drone:init:
228 | desc: Terraform standard initialization
229 | cmds:
230 | - apk add build-base git curl
231 | - apk add --no-cache terraform --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community
232 |
233 | blastradius:
234 | cmds:
235 | - docker run --rm -it -p 5013:5000 -v $(pwd):/data:ro -v $(pwd)/blast:/tmp/results --security-opt apparmor:unconfined --cap-add=SYS_ADMIN blastradius:local
236 |
--------------------------------------------------------------------------------
/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/assets/.gitkeep
--------------------------------------------------------------------------------
/config/aws-filter.yaml:
--------------------------------------------------------------------------------
1 | aws_security_group:
2 | aws_iam_role:
3 | aws_instance:
4 | aws_ec2_transit_gateway_peering_attachment:
5 | aws_ec2_transit_gateway_route_table:
6 | aws_vpc:
7 | aws_subnet:
8 | aws_route_table:
9 | aws_vpc_peering_connection:
10 | aws_db_instance:
11 | aws_rds_cluster:
12 | aws_s3_bucket:
13 |
--------------------------------------------------------------------------------
/config/gcp-filter.yaml:
--------------------------------------------------------------------------------
1 | compute.googleapis.com/Firewall:
2 | regex: ^default-.*
3 | listThese: false
4 | compute.googleapis.com/Subnetwork:
5 | regex: ^default.*
6 | listThese: false
7 | appengine.googleapis.com/Version:
8 | appengine.googleapis.com/Service:
9 | cloudfunctions.googleapis.com/CloudFunction:
10 | compute.googleapis.com/Address:
11 | compute.googleapis.com/Disk:
12 | compute.googleapis.com/BackendBucket:
13 | compute.googleapis.com/BackendService:
14 | compute.googleapis.com/ForwardingRule:
15 | compute.googleapis.com/GlobalForwardingRule:
16 | compute.googleapis.com/HealthCheck:
17 | compute.googleapis.com/Instance:
18 | compute.googleapis.com/TargetHttpProxy:
19 | compute.googleapis.com/TargetHttpsProxy:
20 | compute.googleapis.com/UrlMap:
21 | container.googleapis.com/Cluster:
22 | pubsub.googleapis.com/Subscription:
23 | pubsub.googleapis.com/Topic:
24 | storage.googleapis.com/Bucket:
25 | logging.googleapis.com/LogMetric:
26 | run.googleapis.com/Service:
27 | sqladmin.googleapis.com/Instance:
28 |
--------------------------------------------------------------------------------
/docs/.dockerignore:
--------------------------------------------------------------------------------
1 | # Local .terraform directories
2 | **/.terraform/*
3 | *.tfstate
4 | *.tfstate.*
5 | crash.log
6 | override.tf
7 | override.tf.json
8 | *_override.tf
9 | *_override.tf.json
10 | **/.terraform.lock.hcl/*
11 | .terraform.lock.hcl
12 | *tfplan*
13 | gcp.json
14 | terraform.tfvars
15 | **/gcp.json/*
16 | graph.json
17 | graph.svg
18 | go.sum
19 | go.mod
20 | test/go.sum
21 | test/go.mod
22 |
23 | # Documentation / Node.js
24 | docs/dist/*
25 | docs/*.html
26 | logs
27 | *.log
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 | lerna-debug.log*
32 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
33 | pids
34 | *.pid
35 | *.seed
36 | *.pid.lock
37 | lib-cov
38 | coverage
39 | *.lcov
40 | .nyc_output
41 | .grunt
42 | bower_components
43 | .lock-wscript
44 | build/Release
45 | node_modules/
46 | jspm_packages/
47 | typings/
48 | *.tsbuildinfo
49 | .npm
50 | .eslintcache
51 | .rpt2_cache/
52 | .rts2_cache_cjs/
53 | .rts2_cache_es/
54 | .rts2_cache_umd/
55 | .node_repl_history
56 | *.tgz
57 | .yarn-integrity
58 | .env
59 | .env.test
60 | .cache
61 | index.html
62 | .next
63 | .nuxt
64 | dist
65 | .cache/
66 | .vuepress/dist
67 | .serverless/
68 | .fusebox/
69 | .dynamodb/
70 | .tern-port
71 |
72 | # Docker
73 |
74 | # .vscode
75 | .vscode
76 | renovate.json
77 |
--------------------------------------------------------------------------------
/docs/Dockerfile:
--------------------------------------------------------------------------------
1 | #
2 | # Start from Node
3 | #
4 | FROM node:17.4
5 |
6 | #
7 | # Install CODEDOC CLI (https://codedoc.cc/docs/cli)
8 | #
9 | RUN npm install -g @codedoc/cli
10 |
11 | #
12 | # Create the main Docs folder
13 | #
14 | # This folder should be mounted with the root repo folder,
15 | # but do not forget to exclude `.codedoc/node_modules` from that volume!
16 | #
17 | RUN mkdir -p /home/docs
18 | WORKDIR /home/docs
19 |
20 | #
21 | # Install and serve locally
22 | #
23 | CMD codedoc install && codedoc serve
--------------------------------------------------------------------------------
/docs/build.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | docs:
4 | build: .
5 | ports:
6 | - 3000:3000
7 | # Volume root folder on `/home/blog`,
8 | # but exclude `/home/blog/.codedoc/node_modules" (since the container env should install its own modules).
9 | #
10 | volumes:
11 | - "..:/home/docs"
12 | - "/home/docs/.codedoc/node_modules/"
13 | command: codedoc install && codedoc build
14 |
--------------------------------------------------------------------------------
/docs/build/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/build/.gitkeep
--------------------------------------------------------------------------------
/docs/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | docs:
4 | build: .
5 | ports:
6 | - 3000:3000
7 | # Volume root folder on `/home/blog`,
8 | # but exclude `/home/blog/.codedoc/node_modules" (since the container env should install its own modules).
9 | #
10 | volumes:
11 | - "..:/home/docs"
12 | - "/home/docs/.codedoc/node_modules/"
13 |
--------------------------------------------------------------------------------
/docs/md/404.md:
--------------------------------------------------------------------------------
1 | # 404 Error
2 |
3 | ### This page has not been found
4 |
5 | Please be advised of unknown paths ahead, [head back home here](/).
6 |
--------------------------------------------------------------------------------
/docs/md/_toc.md:
--------------------------------------------------------------------------------
1 | [Home](/)
2 |
3 | [Getting started](/docs/setup/getting-started)
4 |
5 | > :Collapse label="Project Configuration"
6 | >
7 | > [Installing tools](/docs/setup/installing)
8 | >
9 | > [Environment setup](/docs/setup/environment)
10 | >
11 | > [First time running](/docs/setup/first-run)
12 | >
13 | > [Managing existent resources](/docs/setup/management)
14 |
15 | > :Collapse label=Cloud Providers
16 | >
17 | > [Overview](/docs/references)
18 | >
19 | > [Google Cloud Platform](/docs/providers/gcloud)
20 | >
21 | > [Amazon Web Services](/docs/providers/amznaws)
22 | >
23 | > [Microsoft Azure](/docs/providers/msazure)
24 | >
25 | > [Oracle Cloud](/docs/providers/oracle)
26 |
27 | > :Collapse label="About"
28 | >
29 | > [What is this project?](/docs/intro/what-is)
30 | >
31 | > [Whose was it made for?](/docs/intro/about)
32 | >
33 | > [Acknowledgments](/docs/intro/thanks)
34 | >
35 | > [Terms of use](/docs/intro/terms)
36 | >
37 | > [How can I contribute?](/docs/intro/contributions)
38 | >
39 | > [Copyright & Trademark](/docs/intro/legal)
40 |
41 | > :Collapse label="Development"
42 | >
43 | > [Repository Guidelines](/docs/development/guidelines)
44 | >
45 | > [Roadmap](/docs/development/roadmap)
46 | >
47 | > [Running tests](/docs/development/tests)
48 | >
49 | > [Pull Requests](/docs/development/prs)
50 | >
51 | > [Providing Feedback](/docs/development/contact)
52 |
53 |
54 |
--------------------------------------------------------------------------------
/docs/md/docs/code-features.md:
--------------------------------------------------------------------------------
1 | # Code Features
2 |
3 | This is a quick overview of codedoc specific features at your disposal in markdown
4 | `code` elements. For a complete list, please checkout the [official documentation](https://codedoc.cc).
5 | You can also take a look at `docs/md/docs/code-features.md` to see the markdown behind this page.
6 |
7 | > :Buttons
8 | > > :Button label=Official Docs, url=https://codedoc.cc
9 |
10 |
11 |
12 | > ⚠️⚠️
13 | > Do not forget to **REMOVE THIS PAGE** from your actual documentation!
14 | > ⚠️⚠️
15 |
16 |
17 |
18 | ## Hints
19 |
20 | A comment with the following format will cause a hint to be displayed on-hover:
21 |
22 | > `// --> some hint here`
23 |
24 | ```tsx | index.tsx
25 | import { Renderer } from '@connectv/html'; // --> there is a hint on this line
26 |
27 | const MyComp = ({ name }, renderer) => Hellow {name}!
// --> there is also a hint on this line
28 |
29 | const renderer = new Renderer();
30 | renderer.render(
31 |
32 |
33 | {/* --> also this is a hint */}
34 |
35 | )
36 | .on(document.body);
37 | ```
38 |
39 |
40 |
41 | The following syntax styles are supported:
42 |
43 |
44 | ```go
45 | "// --> standard one-liner" // --> standard one-liner
46 | ```
47 |
48 | ```java
49 | "/* --> standard multi-liner */" /* --> standard multi-liner */
50 | ```
51 |
52 | ```py
53 | "# --> python/bash comments" # --> python/bash comments
54 | ```
55 |
56 | ```md
57 | <!--> html comments --> html comments -->
58 | ```
59 |
60 |
61 |
62 |
63 | ## References
64 |
65 | Add a comment with following format in the code will show a link on-hover over the line:
66 |
67 | > `// @see https://www.google.com`
68 |
69 | ```tsx
70 | import { Renderer } from '@connectv/html'; // @see https://github.com/CONNECT-platform/connective-html
71 | ```
72 |
73 | You can also use the markdown link format to give your links a title:
74 |
75 | ````md | --no-wmbar
76 | ```
77 | import { Renderer } from '@connectv/html'; // @see [CONNECTIVE HTML Docs](https://github.com/CONNECT-platform/connective-html)
78 | ```
79 | ````
80 | ```tsx
81 | import { Renderer } from '@connectv/html'; // @see [CONNECTIVE HTML Docs](https://github.com/CONNECT-platform/connective-html)
82 | ```
83 |
84 | You can also use these references to refer to another tab in a tab-component:
85 |
86 | ```md | some-doc.md
87 | > :Tabs
88 | > > :Tab title=First Tab
89 | > >
90 | > > ```tsx
91 | > > import { func } from './other'; // @see tab:Second Tab
92 | > >
93 | > > func(); // --> good stuff will happen now
94 | > > ```
95 | >
96 | > > :Tab title=Second Tab
97 | > >
98 | > > ```tsx
99 | > > export function func() {
100 | > > console.log('Good Stuff!');
101 | > > }
102 | > > ```
103 | ```
104 |
105 |
106 | > :Tabs
107 | > > :Tab title=First Tab
108 | > >
109 | > > ```tsx
110 | > > import { func } from './other'; // @see tab:Second Tab
111 | > >
112 | > > func(); // --> good stuff will happen now
113 | > > ```
114 | >
115 | > > :Tab title=Second Tab
116 | > >
117 | > > ```tsx
118 | > > export function func() {
119 | > > console.log('Good Stuff!');
120 | > > }
121 | > > ```
122 |
123 | Similar syntax styles to hints are supported for references as well:
124 |
125 |
126 | ```js
127 | "// @see [random stuff](https://www.randomlists.com/things)" // @see [random stuff](https://www.randomlists.com/things)
128 | ```
129 |
130 | ```go
131 | "/* @see https://google.com */" /* @see https://google.com */
132 | ```
133 |
134 | ```python
135 | "#@see https://github.com" #@see https://github.com
136 | ```
137 |
138 | ```html
139 |
140 | ```
141 |
142 |
143 | > :ToCPrevNext
--------------------------------------------------------------------------------
/docs/md/docs/development/contact.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/development/contact.md
--------------------------------------------------------------------------------
/docs/md/docs/development/contributions.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/development/contributions.md
--------------------------------------------------------------------------------
/docs/md/docs/development/guidelines.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/development/guidelines.md
--------------------------------------------------------------------------------
/docs/md/docs/development/prs.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/development/prs.md
--------------------------------------------------------------------------------
/docs/md/docs/development/roadmap.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/development/roadmap.md
--------------------------------------------------------------------------------
/docs/md/docs/development/tests.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/development/tests.md
--------------------------------------------------------------------------------
/docs/md/docs/intro/about.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/intro/about.md
--------------------------------------------------------------------------------
/docs/md/docs/intro/legal.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/intro/legal.md
--------------------------------------------------------------------------------
/docs/md/docs/intro/next-steps.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/intro/next-steps.md
--------------------------------------------------------------------------------
/docs/md/docs/intro/terms.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/intro/terms.md
--------------------------------------------------------------------------------
/docs/md/docs/intro/thanks.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/intro/thanks.md
--------------------------------------------------------------------------------
/docs/md/docs/intro/what-is.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/intro/what-is.md
--------------------------------------------------------------------------------
/docs/md/docs/providers/amnzaws.md:
--------------------------------------------------------------------------------
1 | # Amazon AWS
2 |
3 | ## Resources
4 |
5 | - **1x** [Virtual Private Cloud (VPC)](aws-vpc-info)
6 | - **1x** [Sub-network](aws-sub-info) attached to the VPC
7 | - **1x** [Internet Gateway (IGW)](aws-igw-info) to provide access to the VPC
8 | - **1x** [Route Table](aws-route-info) integrating all `VPC`, `Subnet` and the `Internet Gateway (IGW)`
9 | - **1x** [EC2 Instance](aws-ec2-info) attached to the `Subnet`
10 | - **1x** [Relational Database (RDS)](aws-rds-info) of your choice (e.g. MySQL, PostgreSQL)
11 | - **1x** [S3 Storage Bucket](aws-s3-info) inside `Subnet`, configured to store the Terraform's backend state
12 | - **1x** [DynamoDB Database](aws-dynamodb-info), mainly used for preventing that running multiple instances of this Terraform chart corrupt each other.
13 |
14 | #### Terms & Conditions for resource usage
15 |
16 | - Some resources are **only valid for 12 months** and not forever. Please [check the list of resources](aws-sorted-list) to verify each resource maximum usage within the Free-Tier plan.
17 | - EC2 Machines and RDS Databases are limited to `t3.micro` and `db.t2.micro` types respectively.
18 | - AWS provides the free-tier resource usage for all their [global regions](aws-regions) except China (Beijing).
19 | #### Requirements
20 |
21 | - **An active account on AWS** | See: \_[Getting started on AWS](aws-account-create)
22 | - **[Valid Access keys to AWS Account](aws-keys-info)** | See: _[Generating your access keys](aws-keys-create)_
23 |
24 | ## Options
25 |
26 | ### Examples
27 |
28 | ### References
29 |
30 | - [AWS Free-Tier FAQ](aws-faq)
31 | - [AWS Free-Tier Homepage](free-aws)
32 | - [How to set alarms for your Free-Tier account](aws-alarms-free)
33 | - [Terraform AWS Official Provider Documentation](aws-tf-provider)
34 | - [How to prevent charges on your Free-Tier account](aws-prevent-charges)
35 | - [Extended terms and conditions](aws-terms)
36 |
37 |
38 |
39 | [brand]: https://www.hashicorp.com/brand
40 | [disclaimer]: https://www.hashicorp.com/trademark-policy
41 | [guidelines]: https://www.hashicorp.com/community-guidelines
42 | [free-aws]: https://aws.amazon.com/free/?all-free-tier
43 | [free-gcp]: https://cloud.google.com/free
44 | [free-docs-gcp]: https://cloud.google.com/free/docs/gcp-free-tier
45 | [free-azure]: https://azure.microsoft.com/en-us/free/
46 | [azure-faq]: https://azure.microsoft.com/en-us/free/free-account-faq/
47 | [azure-full-terms]: https://azure.microsoft.com/en-us/offers/ms-azr-0044p/
48 | [aws-faq]: https://aws.amazon.com/free/free-tier-faqs/
49 | [go-color-url]: https://github.com/fatih/color
50 | [go-releaser-url]: https://github.com/goreleaser/goreleaser
51 | [go-cobra-url]: https://github.com/spf13/cobra
52 | [shell-has-url]: https://github.com/kdabir/has
53 | [go-prompt-url]: https://github.com/c-bata/go-prompt
54 | [go-task-url]: https://github.com/go-task/task
55 | [go-tfexec-url]: https://github.com/hashicorp/terraform-exec
56 | [docs-repo-url]: https://github.com/CONNECT-platform/codedoc
57 | [aws-key-info]: https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys
58 | [aws-key-create]: https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/
59 | [aws-account-create]: https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/
60 | [aws-vpc-info]: https://aws.amazon.com/vpc/?vpc-blogs.sort-by=item.additionalFields.createdDate&vpc-blogs.sort-order=desc
61 | [aws-igw-info]: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html
62 | [aws-ec2-info]: https://aws.amazon.com/ec2/
63 | [aws-s3-info]: https://aws.amazon.com/s3/
64 | [aws-rds-info]: https://aws.amazon.com/rds/
65 | [aws-route-info]: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html
66 | [aws-sub-info]: https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html
67 | [aws-tf-provider]: https://registry.terraform.io/providers/hashicorp/aws/latest/
68 | [aws-regions]: https://aws.amazon.com/about-aws/global-infrastructure/
69 | [aws-terms]: https://aws.amazon.com/free/terms/
70 | [aws-prevent-charges]: https://aws.amazon.com/premiumsupport/knowledge-center/free-tier-charges/
71 | [aws-alarms-free]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/tracking-free-tier-usage.html#free-budget
72 | [aws-sorted-list]: https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=tier%23always-free%7Ctier%2312monthsfree&awsf.Free%20Tier%20Categories=*all
73 | [aws-dynamodb-info]: https://aws.amazon.com/dynamodb/
74 | [remote-tfstate-url]: https://github.com/cloudposse/terraform-aws-tfstate-backend
75 |
--------------------------------------------------------------------------------
/docs/md/docs/providers/gcloud.md:
--------------------------------------------------------------------------------
1 | # Google Cloud Platform
2 |
3 | > :Tabs
4 | >
5 | > > :Tab title=Available resources
6 | > >
7 | > > - **1x** Virtual Private Cloud [VPC][gcp-vpc-info]
8 | > > - **1x** [Firewall][gcp-firewall-info] attached to the VPC
9 | > > - **1x** [Google Compute Engine][gcp-compute-info] `f1-micro` ([1 shared vCPU - 0.2 dedicatd vCPU][gcp-shared-vcpus] - and 0.6GB of Memory) attached to the `VPC`
10 | > > - **1x** 5GB of [regional storage][gcp-regional-storage] on [Cloud Storage][gcp-cloud-storage]
11 | > > - **1x** 1GB of storage in a [Firestore NoSQL Database][gcp-firestore-storage]
12 | >
13 | > > :Tab title=Terms & Conditions
14 | > >
15 | > > - [Compute Engine Instances ( `f1-micro` ) do not have an external **static** IP address on the free tier][no-free-ip]
16 | > > - You're (as a Free-Tier only) limited to 3 US-based exclusive [zones/regions][gcp-regions] for provisioning your instance. (`us-east1`, `us-west1`, and `us-central1`)
17 | > > - Cloud Storage follows similar rules to the Compute Engine terms, but is also limited to 5,000 Class A operations per month and 50,000 Class B operations per monnth maximum.
18 | > >
19 | > > _Reference:_ [Table of Free-Tier limits][free-tier-limits]
20 | > >
21 | > > - You're limited to 1GB of Egress (outgoing) traffic from North America to the rest of the world.
22 | > >
23 | > > _Related:_ [Pricing on egress rates.][pricing-egress] and [How Google calculates egress usage rates.][usage-egress-gcp]
24 | >
25 | > > :Tab title=More information and official links
26 | > >
27 | > > - [Main landing page on the Free-Tier plan][google-free-landing]
28 | > > - [Limits of the free-tier usage, from the official documentation][free-tier-limits]
29 | > > - [GCP's Free Programs Overview][google-free-docs]
30 | > > - [Eligibility for the Free Tier][free-tier-restrictions]
31 | > > - [Detailed price-list on paid products][gcp-price-list]
32 |
33 | ## Requirements
34 |
35 | ### APIs
36 |
37 | > - [Cloud Resource Manager API][resource-api-info] | [Enable it][resource-api-enable]
38 | > - [Identity and Access Management (IAM) API][iam-api-info] | [Enable it][iam-api-enable]
39 | > - [Cloud Deployment Manager V2 API][cloud-api-info] | [Enable it][cloud-api-enable]
40 | > - [Compute Engine API][compute-api-info] | [Enable it][compute-api-enable]
41 | > - [Cloud Firestore API][firestore-api-info] | [Enable it][firestore-enable-api]
42 |
43 | ## Options
44 |
45 | ### Examples
46 |
47 | ```hcl | /examples/gcp/e2e/main.tf
48 | provider "google" {
49 | region = "your_project_region"
50 | }
51 | provider "google-beta" {
52 | region = "your_project_region"
53 | }
54 |
55 | module "gcp_free" {
56 | source = "https://github.com/gruberdev/tf-free/tree/main/modules/gcp"
57 | gcp_project_id = "your_project_id"
58 | project_region = "your_project_region"
59 | instance_name = "your_resulting_instance_name"
60 | permissions = "permissions_configuration"
61 | bucket_name = "resulting_bucket_name"
62 | network_name = "resulting_network_name"
63 | }
64 | ```
65 |
66 |
67 |
68 | [guidelines]: https://www.hashicorp.com/community-guidelines
69 | [free-gcp]: https://cloud.google.com/free
70 | [free-docs-gcp]: https://cloud.google.com/free/docs/gcp-free-tier
71 | [free-tier-limits]: https://cloud.google.com/free/docs/gcp-free-tier/#free-tier-usage-limits
72 | [free-tier-restrictions]: https://cloud.google.com/free/docs/gcp-free-tier/#free-tier
73 | [google-free-docs]: https://cloud.google.com/free/docs/gcp-free-tier/
74 | [google-free-landing]: https://cloud.google.com/free
75 | [unique-gcp-docs]: https://cloud.google.com/free/docs/what-makes-google-cloud-platform-different
76 | [why-google]: https://cloud.google.com/why-google-cloud
77 | [gcp-price-list]: https://cloud.google.com/pricing/list
78 | [gcp-comparison-docs]: https://cloud.google.com/free/docs/aws-azure-gcp-service-comparison
79 | [pricing-egress]: https://cloud.google.com/vpc/network-pricing#internet_egress
80 | [usage-egress-gcp]: https://cloud.google.com/vpc/network-pricing#vpc-pricing
81 | [gcp-compute-info]: https://cloud.google.com/compute/docs
82 | [gcp-shared-vcpus]: https://cloud.google.com/compute/vm-instance-pricing#cpu-bursting
83 | [gcp-cloud-storage]: https://cloud.google.com/storage
84 | [gcp-vpc-info]: https://cloud.google.com/storage
85 | [gcp-firewall-info]: https://cloud.google.com/storage
86 | [gcp-firestore-storage]: https://cloud.google.com/firestore/docs
87 | [pricing-gcp-calculator]: https://cloud.google.com/products/calculator
88 | [no-free-ip]: https://cloud.google.com/free/docs/gcp-free-tier#always-free-usage-limits
89 | [pricing-egress]: https://cloud.google.com/vpc/network-pricing#internet_egress
90 | [usage-egress-gcp]: https://cloud.google.com/vpc/network-pricing#vpc-pricing
91 | [gcp-compute-info]: https://cloud.google.com/compute/docs
92 | [gcp-shared-vcpus]: https://cloud.google.com/compute/vm-instance-pricing#cpu-bursting
93 | [gcp-cloud-storage]: https://cloud.google.com/storage
94 | [gcp-regional-storage]: https://cloud.google.com/storage/docs/storage-classes#legacy
95 | [gcp-firestore-storage]: https://cloud.google.com/firestore/docs
96 | [gcp-regions]: https://cloud.google.com/compute/docs/regions-zones
97 | [firestore-api-info]: https://cloud.google.com/firestore/docs/reference/rest
98 | [firestore-enable-api]: https://console.cloud.google.com/apis/library/file.googleapis.com
99 | [resource-api-info]: https://cloud.google.com/resource-manager
100 | [resource-api-enable]: https://console.cloud.google.com/apis/library/cloudresourcemanager.googleapis.com
101 | [iam-api-info]: https://cloud.google.com/iam
102 | [iam-api-enable]: https://console.cloud.google.com/apis/library/iam.googleapis.com
103 | [compute-api-info]: https://cloud.google.com/compute
104 | [compute-api-enable]: https://console.cloud.google.com/apis/library/compute.googleapis.com
105 | [cloud-api-info]: https://cloud.google.com/deployment-manager
106 | [cloud-api-enable]: https://console.cloud.google.com/apis/library/deploymentmanager.googleapis.com
107 |
--------------------------------------------------------------------------------
/docs/md/docs/providers/msazure.md:
--------------------------------------------------------------------------------
1 | # Microsoft Azure
2 |
3 | ## Available Resources
4 |
5 | - **1x** [Linux Virtual machine, B1S Standard tier][azure-vm-info]
6 | - **1x** [Windows Virtual machine, B1S Standard tier][azure-vm-info]
7 | - **1x** [Cloud Storage (LRS File Storage)][azure-storage-info]
8 | - **1x** [250GB MySQL Managed Database Instance][azure-sql-free-info]
9 |
10 | #### Terms & Conditions for resource usage
11 |
12 | - Some resources are **only valid for 12 months** and not forever. Please [check the list of resources](azure-free-resources) to verify each resource maximum usage within the Free-Tier plan.
13 | - Microsoft seems to provide very little data on how restricted the free accounts are in the terms of availability in regions around the world.
14 |
15 | ## Options
16 |
17 | ### Examples
18 |
19 | ### References
20 |
21 | - [Official free account Azure main page][azure-free-account]
22 | - [List of free resources][azure-free-resources]
23 | - [Azure Free Account FAQ][azure-free-faq]
24 | - [Azure Full Terms - Free Account][azure-full-terms]
25 |
26 |
27 |
28 | [azure-sql-free-info]: https://azure.microsoft.com/en-us/products/azure-sql/database/
29 | [azure-free-resources]: https://azure.microsoft.com/en-us/free/#12-months-free
30 | [azure-free-account]: https://azure.microsoft.com/en-us/free/
31 | [azure-vm-info]: https://azure.microsoft.com/en-us/services/virtual-machines/
32 | [azure-storage-info]: https://azure.microsoft.com/en-us/services/storage/files/
33 | [azure-full-terms]: https://azure.microsoft.com/en-us/offers/ms-azr-0044p/
34 | [azure-free-faq]: https://azure.microsoft.com/en-us/free/free-account-faq/
35 |
--------------------------------------------------------------------------------
/docs/md/docs/providers/oracle.md:
--------------------------------------------------------------------------------
1 | # Oracle Cloud
2 |
3 | ## Resources
4 |
5 | ## Options
6 |
7 | ### Examples
8 |
9 | ### References
10 |
11 |
12 |
--------------------------------------------------------------------------------
/docs/md/docs/setup/environment.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/setup/environment.md
--------------------------------------------------------------------------------
/docs/md/docs/setup/first-run.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/setup/first-run.md
--------------------------------------------------------------------------------
/docs/md/docs/setup/getting-started.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/setup/getting-started.md
--------------------------------------------------------------------------------
/docs/md/docs/setup/installing.md:
--------------------------------------------------------------------------------
1 | ## CLI
2 |
3 | ### Running tests
4 |
5 | - Tests are available in `test` directory
6 |
7 | - In the test directory, run the below command
8 |
9 | ```
10 | go test
11 | ```
12 |
13 | ### Main Libraries used
14 |
15 | - [fatih/color](go-color-url)
16 | - [goreleaser/goreleaser](go-releaser-url)
17 | - [spf13/cobra](go-cobra-url)
18 | - [kdabir/has](shell-has-url)
19 | - [c-bata/go-prompt](go-prompt-url)
20 | - [go-task/task](go-task-url)
21 | - [hashicorp/terraform-exec](go-tfexec-url)
22 | - [CONNECT-platform/codedoc](docs-repo-url)
23 | - [cloudposse/terraform-aws-tfstate-backend](remote-tfstate-url)
24 |
25 | ---
26 |
27 |
28 |
29 | [go-color-url]: https://github.com/fatih/color
30 | [go-releaser-url]: https://github.com/goreleaser/goreleaser
31 | [go-cobra-url]: https://github.com/spf13/cobra
32 | [shell-has-url]: https://github.com/kdabir/has
33 | [go-prompt-url]: https://github.com/c-bata/go-prompt
34 | [go-task-url]: https://github.com/go-task/task
35 | [go-tfexec-url]: https://github.com/hashicorp/terraform-exec
36 | [docs-repo-url]: https://github.com/CONNECT-platform/codedoc
37 | [remote-tfstate-url]: https://github.com/cloudposse/terraform-aws-tfstate-backend
38 |
--------------------------------------------------------------------------------
/docs/md/docs/setup/management.md:
--------------------------------------------------------------------------------
1 | # CLI
2 |
--------------------------------------------------------------------------------
/docs/md/docs/setup/requirements.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/setup/requirements.md
--------------------------------------------------------------------------------
/docs/md/docs/setup/resources.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/docs/md/docs/setup/resources.md
--------------------------------------------------------------------------------
/docs/md/index.md:
--------------------------------------------------------------------------------
1 | [](https://free.terraform.gruber.dev.br)
2 |
3 | ---
4 |
5 | # Introduction
6 | > **Creating all available resources offered by major cloud providers within free-tier plans, using Terraform to provide, manage and access these resources in a simplified and centralized manner.**
7 |
8 | ### Project's objective
9 |
10 | Every major cloud provider offers a free tier that allows for some kind of resource free of charge, still, learning every cloud and managing these resources can prove burdensome to most.
11 |
12 | The goal is to automate the management of these resources using Terraform as the centralizing tool. It also aims to provide resources for learning and improve your skills as a SRE/DevOps Engineer and as a Terraform user, even if you're developer that never touched cloud infrastructure, nowadays there's great value in learning these tools.
13 |
14 | A CLI tool is part of this project for those who wish a more [KIS][kis-approach]-like approach.
15 |
16 | ---
17 |
18 | # How to use these project's resources:
19 |
20 | There are three main ways to bootstrap this project:
21 |
22 | 1. Using the CLI tool (recommended)
23 | 2. Use Terraform's module directly (advanced)
24 |
25 | The second method exemplified below:
26 |
27 | ```bash | --no-wmbar
28 | terraform apply -auto-approve
29 | ```
30 |
31 | > :Buttons
32 | >
33 | > > :CopyButton
34 |
35 | To visualize the available commands:
36 |
37 | ```bash | --no-wmbar
38 | sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
39 | task --list # Display help message
40 | > * gcp: Build executable binary with GoReleaser.
41 | > * gcp-boot: test
42 | > * gcp-init: Bootstrapping Google Cloud provider testing files
43 | > * gcp-test: Terraform testing (GCP provider)
44 | > * graph: Create beautiful Terraform Graphs
45 | > * heavy-artillery: Destroy all resources but the S3 Backend .and the DynamoDB instances on AWS.
46 | ```
47 |
48 | > :Buttons
49 | >
50 | > > :CopyButton
51 |
52 | ---
53 |
54 | Now, if you want to explicitly call the core module, write a `main.tf` with this content:
55 |
56 | ```hcl | /example/main.tf
57 | // Create a main.tf file anywhere with Terraform installed and copy-paste this code
58 |
59 | module "tf-free" {
60 | source = "github.com/gruberdev/tf-free"
61 |
62 | /*!*/ enable_aws = true // @see [AWS documentation](/docs/providers/amznaws)
63 | /*!*/ enable_s3_backend = true // @see [using a remote S3 on AWS reference](/docs/setup/backend)
64 | aws_account_id = "your-aws-access-id"
65 | aws_account_key = "your-aws-secret-key"
66 | aws_default_region = "us-west1"
67 |
68 | /*!*/ enable_gcp = true // @see [GCP's documentation](/docs/providers/gcloud)
69 | gcp_project_id = "testing-project-1"
70 | gcp_project_region = "us-west-1"
71 | gcp_instance_name = "gcp-machine"
72 |
73 | /*!*/ enable_azure = true // @see [Azure's documentation](/docs/providers/msazure)
74 |
75 | /*!*/ enable_oracle = true // @see [Oracle's documentation](/docs/providers/msazure)
76 | }
77 | ```
78 |
79 | > :Buttons
80 | >
81 | > > :CopyButton
82 |
83 |
84 |
85 | If you're unsure what your credentials are for each cloud provider, take a look at [Obtaining credentials](/docs/setup/first-run).
86 |
87 | > :Buttons
88 | >
89 | > > :Button icon=true, label=double_arrow, url=/docs/setup/getting-started
90 |
91 | ---
92 |
93 |
94 |
95 | [drone-img]: https://img.shields.io/drone/build/gruberdev/tf-free?label=Pipeline%20Status&color=46bac0&labelColor=1F1F1F&logo=Drone&style=for-the-badge&server=https%3A%2F%2Fdrone.gruber.dev.br
96 | [docs-img]: https://img.shields.io/badge/read%20documentation-online?style=flat-square&logo=zeit&color=black
97 |
98 |
99 |
100 | [brand]: https://www.hashicorp.com/brand
101 | [disclaimer]: https://www.hashicorp.com/trademark-policy
102 | [guidelines]: https://www.hashicorp.com/community-guidelines
103 | [free-aws]: https://aws.amazon.com/free/?all-free-tier
104 | [free-gcp]: https://cloud.google.com/free
105 | [free-docs-gcp]: https://cloud.google.com/free/docs/gcp-free-tier
106 | [free-azure]: https://azure.microsoft.com/en-us/free/
107 | [azure-faq]: https://azure.microsoft.com/en-us/free/free-account-faq/
108 | [azure-full-terms]: https://azure.microsoft.com/en-us/offers/ms-azr-0044p/
109 | [aws-faq]: https://aws.amazon.com/free/free-tier-faqs/
110 | [go-color-url]: https://github.com/fatih/color
111 | [go-releaser-url]: https://github.com/goreleaser/goreleaser
112 | [go-cobra-url]: https://github.com/spf13/cobra
113 | [shell-has-url]: https://github.com/kdabir/has
114 | [go-prompt-url]: https://github.com/c-bata/go-prompt
115 | [go-task-url]: https://github.com/go-task/task
116 | [go-tfexec-url]: https://github.com/hashicorp/terraform-exec
117 | [docs-repo-url]: https://github.com/CONNECT-platform/codedoc
118 | [aws-key-info]: https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys
119 | [aws-key-create]: https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/
120 | [aws-account-create]: https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/
121 | [aws-vpc-info]: https://aws.amazon.com/vpc/?vpc-blogs.sort-by=item.additionalFields.createdDate&vpc-blogs.sort-order=desc
122 | [aws-igw-info]: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html
123 | [aws-ec2-info]: https://aws.amazon.com/ec2/
124 | [aws-s3-info]: https://aws.amazon.com/s3/
125 | [aws-rds-info]: https://aws.amazon.com/rds/
126 | [aws-route-info]: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html
127 | [aws-sub-info]: https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html
128 | [aws-tf-provider]: https://registry.terraform.io/providers/hashicorp/aws/latest/
129 | [aws-regions]: https://aws.amazon.com/about-aws/global-infrastructure/
130 | [aws-terms]: https://aws.amazon.com/free/terms/
131 | [aws-prevent-charges]: https://aws.amazon.com/premiumsupport/knowledge-center/free-tier-charges/
132 | [aws-alarms-free]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/tracking-free-tier-usage.html#free-budget
133 | [aws-sorted-list]: https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=tier%23always-free%7Ctier%2312monthsfree&awsf.Free%20Tier%20Categories=*all
134 | [aws-dynamodb-info]: https://aws.amazon.com/dynamodb/
135 | [remote-tfstate-url]: https://github.com/cloudposse/terraform-aws-tfstate-backend
136 |
--------------------------------------------------------------------------------
/docs/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "cleanUrls": true
3 | }
--------------------------------------------------------------------------------
/examples/aws/e2e/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | No modules.
5 |
6 | ### Inputs
7 |
8 | No inputs.
9 |
10 | ### Outputs
11 |
12 | No outputs.
13 |
14 |
--------------------------------------------------------------------------------
/examples/aws/e2e/main.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/examples/aws/e2e/main.tf
--------------------------------------------------------------------------------
/examples/aws/e2e/outputs.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/examples/aws/e2e/outputs.tf
--------------------------------------------------------------------------------
/examples/aws/e2e/variables.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/examples/aws/e2e/variables.tf
--------------------------------------------------------------------------------
/examples/aws/unit/ec2/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | | Name | Source | Version |
5 | |------|--------|---------|
6 | | ec2 | ../../../../modules/aws/ec2 | n/a |
7 | | vpc | ../../../../modules/aws/vpc | n/a |
8 |
9 | ### Inputs
10 |
11 | | Name | Description | Type | Default |
12 | |------|-------------|------|---------|
13 | | ami\_id | n/a | `string` | n/a |
14 | | aws\_default\_region | n/a | `string` | n/a |
15 | | ec2\_enable | n/a | `bool` | `true` |
16 | | ssh\_name | n/a | `string` | n/a |
17 | | ssh\_public | n/a | `string` | n/a |
18 | | subnet\_region | n/a | `string` | n/a |
19 |
20 | ### Outputs
21 |
22 | | Name | Description |
23 | |------|-------------|
24 | | public\_ip | List of public IP addresses assigned to the instances, if applicable |
25 |
26 |
--------------------------------------------------------------------------------
/examples/aws/unit/ec2/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = var.aws_default_region
3 | }
4 |
5 | module "vpc" {
6 | source = "../../../../modules/aws/vpc"
7 | region = var.aws_default_region
8 | }
9 |
10 | module "ec2" {
11 | source = "../../../../modules/aws/ec2"
12 | count = var.ec2_enable ? 1 : 0
13 | vpc_id = module.vpc.id
14 | public_subnet_id = module.vpc.public_subnets[0]
15 | ami = var.ami_id
16 |
17 | seed_data = < index.html
20 | nohup busybox httpd -f -p 80 &
21 | EOF
22 | ssh_name = var.ssh_name
23 | ssh_public = var.ssh_public
24 | depends_on = [
25 | module.vpc.public_subnets
26 | ]
27 | }
28 |
29 |
30 | output "public_ip" {
31 | description = "List of public IP addresses assigned to the instances, if applicable"
32 | value = module.ec2.*.public_ip
33 | sensitive = true
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/examples/aws/unit/ec2/variables.tf:
--------------------------------------------------------------------------------
1 | variable "ssh_name" {
2 | type = string
3 | }
4 | variable "ssh_public" {
5 | type = string
6 | }
7 | variable "aws_default_region" {
8 | type = string
9 | }
10 | variable "subnet_region" {
11 | type = string
12 | }
13 | variable "ami_id" {
14 | type = string
15 | }
16 | variable "ec2_enable" {
17 | type = bool
18 | default = true
19 | }
20 |
--------------------------------------------------------------------------------
/examples/aws/unit/rds/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | | Name | Source | Version |
5 | |------|--------|---------|
6 | | rds | ../../../../modules/aws/rds | n/a |
7 | | vpc | ../../../../modules/aws/vpc | n/a |
8 |
9 | ### Inputs
10 |
11 | | Name | Description | Type | Default |
12 | |------|-------------|------|---------|
13 | | allocated\_storage | n/a | `number` | `5` |
14 | | aws\_default\_region | n/a | `string` | n/a |
15 | | database\_name | n/a | `string` | `"newtable"` |
16 | | db\_port | n/a | `number` | `5432` |
17 | | engine\_name | n/a | `string` | n/a |
18 | | engine\_version | n/a | `string` | n/a |
19 | | instance\_class | n/a | `string` | n/a |
20 | | name | n/a | `string` | n/a |
21 | | password | n/a | `string` | n/a |
22 | | rds\_enable | n/a | `bool` | `true` |
23 | | username | n/a | `string` | n/a |
24 |
25 | ### Outputs
26 |
27 | | Name | Description |
28 | |------|-------------|
29 | | db\_id | List of key names of instances |
30 | | db\_port | List of public IP addresses assigned to the instances, if applicable |
31 |
--------------------------------------------------------------------------------
/examples/aws/unit/rds/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = var.aws_default_region
3 | }
4 |
5 | module "vpc" {
6 | source = "../../../../modules/aws/vpc"
7 | region = var.aws_default_region
8 | }
9 | module "rds" {
10 | source = "../../../../modules/aws/rds"
11 | count = var.rds_enable ? 1 : 0
12 | db_user = var.username
13 | name = var.name
14 | db_engine = var.engine_name
15 | db_version = var.engine_version
16 | region = var.aws_default_region
17 | db_name = var.database_name
18 | db_password = var.password
19 | vpc_id = module.vpc.id
20 | vpc_cidr_block = module.vpc.cidr_block
21 | vpc_subnet_ids = ["${module.vpc.database_subnets[0]}", "${module.vpc.database_subnets[1]}"]
22 | }
--------------------------------------------------------------------------------
/examples/aws/unit/rds/outputs.tf:
--------------------------------------------------------------------------------
1 |
2 |
3 | output "db_port" {
4 | description = "List of public IP addresses assigned to the instances, if applicable"
5 | value = concat(module.rds.*.db_default_instance_port, [""])[0]
6 |
7 | }
8 | output "db_id" {
9 | description = "List of key names of instances"
10 | value = concat(module.rds.*.db_default_instance_id, [""])[0]
11 | }
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/aws/unit/rds/variables.tf:
--------------------------------------------------------------------------------
1 | variable "aws_default_region" {
2 | type = string
3 | }
4 | variable "name" {
5 | type = string
6 | }
7 | variable "engine_name" {
8 | type = string
9 | }
10 | variable "engine_version" {
11 | type = string
12 | }
13 | variable "instance_class" {
14 | type = string
15 | }
16 |
17 | variable "rds_enable" {
18 | type = bool
19 | default = true
20 | }
21 |
22 | variable "username" {
23 | sensitive = true
24 | type = string
25 | }
26 | variable "password" {
27 | sensitive = true
28 | type = string
29 | }
30 | variable "allocated_storage" {
31 | type = number
32 | default = 5
33 | }
34 |
35 | variable "database_name" {
36 | type = string
37 | default = "newtable"
38 | }
39 |
40 | variable "db_port" {
41 | type = number
42 | default = 5432
43 | }
44 |
--------------------------------------------------------------------------------
/examples/azure/e2e/main.tf:
--------------------------------------------------------------------------------
1 | provider "azurerm" {
2 | features {}
3 | }
4 |
5 | module "azure" {
6 | source = "../../../modules/azure"
7 | resource_group_name = var.resource_group_name
8 | location = var.location
9 | /* linux_hostname = var.linux_vm
10 | windows_hostname = var.windows_vm */
11 | }
12 |
--------------------------------------------------------------------------------
/examples/azure/e2e/outputs.tf:
--------------------------------------------------------------------------------
1 | /* output "linux_name" {
2 |
3 | }
4 |
5 | output "windows_name" {
6 | value = azure.
7 | } */
--------------------------------------------------------------------------------
/examples/azure/e2e/variables.tf:
--------------------------------------------------------------------------------
1 | variable "location" {
2 | type = string
3 | default = "East US"
4 | }
5 | variable "resource_group_name" {
6 | type = string
7 | default = "my-group"
8 | }
9 | /* variable "linux_vm" {
10 | type = string
11 | default = "my-linux"
12 | }
13 | variable "windows_vm" {
14 | type = string
15 | default = "my-windows"
16 | } */
--------------------------------------------------------------------------------
/examples/azure/unit/compute/main.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/examples/azure/unit/compute/main.tf
--------------------------------------------------------------------------------
/examples/azure/unit/compute/outputs.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/examples/azure/unit/compute/outputs.tf
--------------------------------------------------------------------------------
/examples/azure/unit/compute/variables.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/examples/azure/unit/compute/variables.tf
--------------------------------------------------------------------------------
/examples/azure/unit/db/main.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/examples/azure/unit/db/main.tf
--------------------------------------------------------------------------------
/examples/azure/unit/db/variables.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/examples/azure/unit/db/variables.tf
--------------------------------------------------------------------------------
/examples/gcp/e2e/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/gcp/e2e/main.tf:
--------------------------------------------------------------------------------
1 | provider "google" {
2 | region = var.gcp_project_region
3 | }
4 | provider "google-beta" {
5 | region = var.gcp_project_region
6 | }
7 |
8 | module "google_cloud" {
9 | source = "../../../modules/gcp"
10 | gcp_project_id = var.gcp_project_id
11 | project_region = var.gcp_project_region
12 | instance_name = var.gcp_instance_name
13 | permissions = var.gcp_storage_permissions
14 | bucket_name = var.gcp_bucket_name
15 | network_name = var.gcp_network_name
16 | }
17 |
18 | output "gcp_public_ip" {
19 | value = module.google_cloud.machine_ip
20 | sensitive = true
21 | }
22 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/gcp/e2e/terraform.tfvars.example:
--------------------------------------------------------------------------------
1 | gcp_instance_name = "example-machine"
2 | gcp_project_region = ""
3 | gcp_project_id = ""
4 | gcp_bucket_name = ""
5 | gcp_network_name = ""
6 | gcp_storage_permissions = "publicread"
--------------------------------------------------------------------------------
/examples/gcp/e2e/variables.tf:
--------------------------------------------------------------------------------
1 | variable "gcp_project_region" {
2 | type = string
3 | }
4 |
5 | variable "gcp_project_id" {
6 | type = string
7 | }
8 |
9 | variable "gcp_network_name" {
10 | type = string
11 | }
12 |
13 | variable "gcp_bucket_name" {
14 | type = string
15 | }
16 |
17 | variable "gcp_storage_permissions" {
18 | type = string
19 | default = "publicread"
20 | }
21 |
22 | variable "gcp_instance_name" {
23 | type = string
24 | }
--------------------------------------------------------------------------------
/examples/gcp/unit/compute/README.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/gcp/unit/compute/main.tf:
--------------------------------------------------------------------------------
1 | provider "google" {
2 | region = var.gcp_project_region
3 | }
4 | provider "google-beta" {
5 | region = var.gcp_project_region
6 | }
7 |
8 | resource "google_compute_instance" "gcp_example" {
9 | name = var.gcp_instance_name
10 | machine_type = "f1-micro"
11 | zone = "${var.gcp_project_region}-b"
12 |
13 | boot_disk {
14 | initialize_params {
15 | image = "debian-cloud/debian-10"
16 | size = 30
17 | type = "pd-standard"
18 | }
19 | }
20 |
21 | network_interface {
22 | network = "default"
23 | access_config {
24 | }
25 | }
26 | tags = [
27 | "web",
28 | "ssh"
29 | ]
30 | }
31 |
32 | output "instance_id" {
33 | value = google_compute_instance.gcp_example.instance_id
34 | }
35 | output "resulting_name" {
36 | value = google_compute_instance.gcp_example.name
37 | }
38 | output "resulting_type" {
39 | value = google_compute_instance.gcp_example.machine_type
40 | }
41 |
42 |
43 |
--------------------------------------------------------------------------------
/examples/gcp/unit/compute/terraform.tfvars.example:
--------------------------------------------------------------------------------
1 | gcp_instance_name = "example-machine"
2 | gcp_project_region = ""
3 | gcp_project_id = ""
4 |
--------------------------------------------------------------------------------
/examples/gcp/unit/compute/variables.tf:
--------------------------------------------------------------------------------
1 | variable "gcp_project_region" {
2 | type = string
3 | }
4 | variable "gcp_project_id" {
5 | type = string
6 | }
7 | variable "gcp_instance_name" {
8 | type = string
9 | }
--------------------------------------------------------------------------------
/examples/gcp/unit/storage/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/gcp/unit/storage/main.tf:
--------------------------------------------------------------------------------
1 | provider "google" {
2 | region = var.gcp_project_region
3 | }
4 | provider "google-beta" {
5 | project = var.gcp_project_id
6 | region = var.gcp_project_region
7 | }
8 |
9 | module "gcp_vpc" {
10 | vpc_name = var.gcp_network_name
11 | source = "../../../../modules/gcp/vpc"
12 | google_project = var.gcp_project_id
13 | }
14 |
15 | module "gcp_storage" {
16 | depends_on = [
17 | module.gcp_vpc.network_name,
18 | ]
19 | source = "../../../../modules/gcp/storage"
20 | project_id = var.gcp_project_id
21 | name = var.gcp_bucket_name
22 | permissions = var.gcp_bucket_permissions
23 | /* firestore_name = var.firestore_name */
24 | region = var.gcp_project_region
25 | network_name = module.gcp_vpc.network_name
26 | }
27 |
28 | output "bucket_name" {
29 | description = "Name of the GCS bucket that will receive the objects."
30 | value = module.gcp_storage.bucket_name
31 | }
32 |
--------------------------------------------------------------------------------
/examples/gcp/unit/storage/terraform.tfvars.example:
--------------------------------------------------------------------------------
1 | gcp_instance_name = "example-machine"
2 | gcp_project_region = ""
3 | gcp_project_id = ""
4 | gcp_bucket_name = ""
5 | gcp_network_name = ""
6 | gcp_storage_permissions = "publicread"
--------------------------------------------------------------------------------
/examples/gcp/unit/storage/variables.tf:
--------------------------------------------------------------------------------
1 | variable "gcp_project_region" {
2 | type = string
3 | }
4 | variable "gcp_project_id" {
5 | type = string
6 | }
7 | variable "gcp_network_name" {
8 | type = string
9 | }
10 |
11 | variable "gcp_bucket_name" {
12 | type = string
13 | }
14 |
15 | variable "gcp_bucket_permissions" {
16 | type = string
17 | default = "publicread"
18 | }
--------------------------------------------------------------------------------
/examples/gcp/unit/vpc/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/gcp/unit/vpc/main.tf:
--------------------------------------------------------------------------------
1 | provider "google" {
2 | region = var.gcp_project_region
3 | }
4 | provider "google-beta" {
5 | project = var.gcp_project_id
6 | region = var.gcp_project_region
7 | }
8 |
9 | module "gcp_vpc" {
10 | vpc_name = var.gcp_network_name
11 | google_project = var.gcp_project_id
12 | source = "../../../../modules/gcp/vpc"
13 | }
14 |
15 | module "gcp_firewall" {
16 | depends_on = [
17 | module.gcp_vpc.network_name
18 | ]
19 | source = "../../../../modules/gcp/firewall"
20 | network_name = module.gcp_vpc.network_name
21 | }
22 |
--------------------------------------------------------------------------------
/examples/gcp/unit/vpc/terraform.tfvars.example:
--------------------------------------------------------------------------------
1 | gcp_network_name = "example-network"
2 | gcp_project_region = ""
3 | gcp_project_id = ""
--------------------------------------------------------------------------------
/examples/gcp/unit/vpc/variables.tf:
--------------------------------------------------------------------------------
1 | variable "gcp_project_region" {
2 | type = string
3 | }
4 | variable "gcp_project_id" {
5 | type = string
6 | }
7 | variable "gcp_network_name" {
8 | type = string
9 | }
--------------------------------------------------------------------------------
/main.tf:
--------------------------------------------------------------------------------
1 |
2 | resource "random_string" "namespace" {
3 | length = 2
4 | special = false
5 | number = false
6 | upper = false
7 | }
8 |
9 | resource "random_string" "s3_name" {
10 | length = 6
11 | special = false
12 | number = false
13 | upper = false
14 | }
15 |
16 | resource "random_string" "bucket_name" {
17 | length = 10
18 | special = false
19 | number = false
20 | upper = false
21 | }
22 |
23 | module "terraform_state_backend" {
24 | source = "cloudposse/tfstate-backend/aws"
25 | version = "0.38.1"
26 | namespace = random_string.namespace.result
27 | stage = var.backend_stage
28 | name = random_string.s3_name.result
29 | s3_bucket_name = random_string.bucket_name.result
30 | attributes = ["state"]
31 | terraform_backend_config_file_path = "."
32 | terraform_backend_config_file_name = "backend.tf"
33 | force_destroy = var.backend_destroy
34 | depends_on = [
35 | null_resource.backend
36 | ]
37 | }
38 |
39 | resource "null_resource" "backend" {
40 | triggers = {
41 | backend_destroy = var.backend_destroy
42 | }
43 | lifecycle {
44 | prevent_destroy = true
45 | }
46 | }
47 |
48 | module "google_cloud" {
49 | source = "./modules/gcp"
50 | gcp_project_id = var.gcp_project_id
51 | project_region = var.gcp_project_region
52 | instance_name = var.gcp_instance_name
53 | permissions = var.gcp_storage_permissions
54 |
55 | depends_on = [
56 | module.terraform_state_backend.dynamodb_table_name,
57 | module.terraform_state_backend.dynamodb_table_id,
58 | module.terraform_state_backend.terraform_backend_config
59 | ]
60 | }
61 |
62 | module "aws" {
63 | source = "./modules/aws"
64 | ec2_enable = var.ec2_aws
65 | rds_enable = var.rds_aws
66 | }
67 |
68 | // module "azure" {
69 | // source = "./modules/azure"
70 | // }
--------------------------------------------------------------------------------
/modules/aws/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | | Name | Source | Version |
5 | |------|--------|---------|
6 | | ec2 | ./ec2 | n/a |
7 | | rds | ./rds | n/a |
8 | | vpc | ./vpc | n/a |
9 |
10 | ### Inputs
11 |
12 | | Name | Description | Type | Default |
13 | |------|-------------|------|---------|
14 | | ec2\_enable | AWS Profile | `bool` | `true` |
15 | | ec2\_ssh\_name | The SSH Key Name | `string` | `"free-tier-ec2-key"` |
16 | | ec2\_ssh\_public | The local path to the SSH Public Key | `string` | `"~/.ssh-temp/id_rsa.pub"` |
17 | | profile | AWS Profile | `string` | `"terraform"` |
18 | | rds\_enable | AWS Profile | `bool` | `true` |
19 | | rds\_password | Region for the RDS database | `string` | `"testingdatabase89372934279"` |
20 | | rds\_user | Region for AWS resources | `string` | `"testing"` |
21 | | region | Region for AWS resources | `string` | `"us-east-1"` |
22 |
23 | ### Outputs
24 |
25 | | Name | Description |
26 | |------|-------------|
27 | | db\_id | List of key names of instances |
28 | | ec2\_ipv6\_addresses | List of assigned IPv6 addresses of instances |
29 | | ec2\_key\_name | List of key names of instances |
30 | | ec2\_password\_data | List of Base-64 encoded encrypted password data for the instance |
31 | | ec2\_private\_ip | List of private IP addresses assigned to the instances |
32 | | ec2\_public\_ip | List of public IP addresses assigned to the instances, if applicable |
33 |
34 |
35 | ## Example
36 |
37 | ```hcl
38 | provider "aws" {
39 | region = var.aws_default_region
40 | access_key = var.aws_account_id
41 | secret_key = var.aws_account_key
42 | }
43 |
44 | module "vpc" {
45 | source = "../../../../modules/aws/vpc"
46 | name = "vpc-test-ec2"
47 | }
48 |
49 | module "public_subnet" {
50 | source = "../../../../modules/aws/subnet"
51 | name = "subnet-test-ec2"
52 | availability_zone = var.subnet_region
53 | vpc_id = module.vpc.id
54 | }
55 |
56 | module "internet_gateway" {
57 | source = "../../../../modules/aws/gateway"
58 | name = "igw-test-ec2"
59 | vpc_id = module.vpc.id
60 | }
61 |
62 | module "route_table" {
63 | source = "../../../../modules/aws/firewall"
64 |
65 | name = "table-test-ec2"
66 | vpc_id = module.vpc.id
67 | internet_gateway_id = module.internet_gateway.id
68 | public_subnet_id = module.public_subnet.id
69 | }
70 |
71 | module "ec2" {
72 | source = "../../../../modules/aws/ec2"
73 | name = "ec2-test-ec2"
74 | vpc_id = module.vpc.id
75 | ami = var.ami_id
76 | seed_data = < index.html
79 | nohup busybox httpd -f -p 80 &
80 | EOF
81 | public_subnet_id = module.public_subnet.id
82 | ssh_name = var.ssh_name
83 | ssh_public = var.ssh_public
84 | }
85 |
86 | ```
87 |
--------------------------------------------------------------------------------
/modules/aws/ec2/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | No modules.
5 |
6 | ### Inputs
7 |
8 | | Name | Description | Type | Default |
9 | |------|-------------|------|---------|
10 | | ami | The Amazon Machine Image | `string` | `"ami-04b9e92b5572fa0d1"` |
11 | | instance\_type | The EC2 Instance type | `string` | `"t2.micro"` |
12 | | name | The Name of the EC2 | `string` | `"Free Tier EC2"` |
13 | | public\_subnet\_id | The ID of the Public Subnet | `string` | n/a |
14 | | security\_group\_description | The Description of the EC2 Security Group | `string` | `"Free Tier EC2 Security Group"` |
15 | | security\_group\_name | The Name of the EC2 Security Group | `string` | `"Free Tier EC2 Security Group"` |
16 | | seed\_data | The local path to the SSH Public Key | `string` | `""` |
17 | | ssh\_name | The SSH Key Name | `string` | `"free-tier-ec2-key"` |
18 | | ssh\_public | The local path to the SSH Public Key | `string` | n/a |
19 | | vpc\_id | The ID of the VPC | `string` | n/a |
20 |
21 | ### Outputs
22 |
23 | | Name | Description |
24 | |------|-------------|
25 | | arn | The ARN of the EC2 |
26 | | id | The ID of the EC2 |
27 | | ipv6\_addresses | List of assigned IPv6 addresses of instances |
28 | | names | List of key names of instances |
29 | | password\_data | List of Base-64 encoded encrypted password data for the instance |
30 | | private\_ip | List of private IP addresses assigned to the instances |
31 | | public\_dns | List of public DNS names assigned to the instances. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC |
32 | | public\_ip | List of public IP addresses assigned to the instances, if applicable |
33 | | security\_group\_id | List of key names of instances |
34 |
35 |
--------------------------------------------------------------------------------
/modules/aws/ec2/main.tf:
--------------------------------------------------------------------------------
1 | resource "aws_security_group" "security_group" {
2 | name = var.security_group_name
3 | description = var.security_group_description
4 |
5 | vpc_id = var.vpc_id
6 |
7 | ingress {
8 | from_port = 22
9 | to_port = 22
10 | protocol = "tcp"
11 | cidr_blocks = ["0.0.0.0/0"]
12 | }
13 |
14 | ingress {
15 | from_port = 80
16 | to_port = 80
17 | protocol = "tcp"
18 | cidr_blocks = ["0.0.0.0/0"]
19 | }
20 |
21 | ingress {
22 | from_port = 443
23 | to_port = 443
24 | protocol = "tcp"
25 | cidr_blocks = ["0.0.0.0/0"]
26 | }
27 |
28 | egress {
29 | from_port = 0
30 | to_port = 0
31 | protocol = "-1"
32 | cidr_blocks = ["0.0.0.0/0"]
33 | }
34 |
35 | tags = {
36 | Name = var.security_group_name
37 | }
38 | }
39 |
40 | resource "aws_instance" "ec2" {
41 |
42 | ami = var.ami
43 | instance_type = var.instance_type
44 |
45 | subnet_id = var.public_subnet_id
46 | vpc_security_group_ids = [aws_security_group.security_group.id]
47 | associate_public_ip_address = true
48 | user_data = var.seed_data
49 |
50 | tags = {
51 | Name = var.name
52 | }
53 | }
54 |
55 |
56 | resource "aws_key_pair" "ec2_key_pair" {
57 | key_name = var.ssh_name
58 | public_key = var.ssh_public
59 | }
60 |
--------------------------------------------------------------------------------
/modules/aws/ec2/outputs.tf:
--------------------------------------------------------------------------------
1 | output "id" {
2 | description = "The ID of the EC2"
3 | value = concat(aws_instance.ec2.*.id, [""])[0]
4 | }
5 |
6 | output "arn" {
7 | description = "The ARN of the EC2"
8 | value = concat(aws_instance.ec2.*.arn, [""])[0]
9 | }
10 |
11 | output "public_ip" {
12 | description = "List of public IP addresses assigned to the instances, if applicable"
13 | value = aws_instance.ec2.*.public_ip
14 | sensitive = true
15 | }
16 |
17 | output "ipv6_addresses" {
18 | description = "List of assigned IPv6 addresses of instances"
19 | value = aws_instance.ec2.*.ipv6_addresses
20 | sensitive = true
21 | }
22 |
23 | output "private_ip" {
24 | description = "List of private IP addresses assigned to the instances"
25 | value = aws_instance.ec2.*.private_ip
26 | sensitive = true
27 | }
28 |
29 | output "password_data" {
30 | description = "List of Base-64 encoded encrypted password data for the instance"
31 | value = aws_instance.ec2.*.password_data
32 | sensitive = true
33 | }
34 |
35 | output "public_dns" {
36 | description = "List of public DNS names assigned to the instances. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
37 | value = aws_instance.ec2.*.public_dns
38 | }
39 |
40 | output "names" {
41 | description = "List of key names of instances"
42 | value = aws_instance.ec2.*.key_name
43 | }
44 |
45 | output "security_group_id" {
46 | description = "List of key names of instances"
47 | value = aws_security_group.security_group.id
48 | }
49 |
--------------------------------------------------------------------------------
/modules/aws/ec2/variables.tf:
--------------------------------------------------------------------------------
1 | variable "name" {
2 | description = "The Name of the EC2"
3 | type = string
4 | default = "Free Tier EC2"
5 | }
6 |
7 | variable "security_group_name" {
8 | description = "The Name of the EC2 Security Group"
9 | type = string
10 | default = "Free Tier EC2 Security Group"
11 | }
12 |
13 | variable "security_group_description" {
14 | description = "The Description of the EC2 Security Group"
15 | type = string
16 | default = "Free Tier EC2 Security Group"
17 | }
18 |
19 | variable "ami" {
20 | description = "The Amazon Machine Image"
21 | type = string
22 | default = "ami-04b9e92b5572fa0d1" # Ubuntu 18.04 LTS (64-bit x86) Free Tier eligible
23 | }
24 |
25 | variable "instance_type" {
26 | description = "The EC2 Instance type"
27 | type = string
28 | default = "t2.micro" # Free Tier eligible
29 | }
30 |
31 | variable "vpc_id" {
32 | description = "The ID of the VPC"
33 | sensitive = true
34 | type = string
35 | }
36 |
37 | variable "public_subnet_id" {
38 | description = "The ID of the Public Subnet"
39 | sensitive = true
40 | type = string
41 | }
42 |
43 | variable "ssh_name" {
44 | description = "The SSH Key Name"
45 | type = string
46 | default = "free-tier-ec2-key"
47 | }
48 |
49 | variable "ssh_public" {
50 | description = "The local path to the SSH Public Key"
51 | sensitive = true
52 | type = string
53 | }
54 | variable "seed_data" {
55 | description = "The local path to the SSH Public Key"
56 | default = ""
57 | type = string
58 | }
59 |
--------------------------------------------------------------------------------
/modules/aws/firewall/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | No modules.
5 |
6 | ### Inputs
7 |
8 | | Name | Description | Type | Default |
9 | |------|-------------|------|---------|
10 | | internet\_gateway\_id | The ID of the Internet Gateway | `string` | n/a |
11 | | name | The Name of the Route Table | `string` | `"Free Tier Route Table"` |
12 | | public\_subnet\_id | The ID of the Public Subnet | `string` | n/a |
13 | | should\_be\_created | Should the Route Table be created? | `bool` | `true` |
14 | | vpc\_id | The ID of the VPC | `string` | n/a |
15 |
16 | ### Outputs
17 |
18 | | Name | Description |
19 | |------|-------------|
20 | | id | The ID of the Route Table |
21 |
22 |
--------------------------------------------------------------------------------
/modules/aws/firewall/main.tf:
--------------------------------------------------------------------------------
1 | resource "aws_route_table" "route_table" {
2 | vpc_id = var.vpc_id
3 |
4 | route {
5 | cidr_block = "0.0.0.0/0"
6 | gateway_id = var.internet_gateway_id
7 | }
8 |
9 | tags = {
10 | Name = var.name
11 | }
12 | }
13 |
14 | resource "aws_route_table_association" "route_table_association" {
15 | subnet_id = var.public_subnet_id
16 | route_table_id = concat(aws_route_table.route_table.*.id, [""])[0]
17 | }
18 |
--------------------------------------------------------------------------------
/modules/aws/firewall/outputs.tf:
--------------------------------------------------------------------------------
1 | output "id" {
2 | description = "The ID of the Route Table"
3 | value = concat(aws_route_table.route_table.*.id, [""])[0]
4 | }
5 |
--------------------------------------------------------------------------------
/modules/aws/firewall/variables.tf:
--------------------------------------------------------------------------------
1 | variable "name" {
2 | description = "The Name of the Route Table"
3 | type = string
4 | default = "Free Tier Route Table"
5 | }
6 |
7 | variable "vpc_id" {
8 | description = "The ID of the VPC"
9 | sensitive = true
10 | type = string
11 | }
12 |
13 | variable "internet_gateway_id" {
14 | description = "The ID of the Internet Gateway"
15 | type = string
16 | }
17 |
18 | variable "public_subnet_id" {
19 | description = "The ID of the Public Subnet"
20 | sensitive = true
21 | type = string
22 | }
23 |
--------------------------------------------------------------------------------
/modules/aws/gateway/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | No modules.
5 |
6 | ### Inputs
7 |
8 | | Name | Description | Type | Default |
9 | |------|-------------|------|---------|
10 | | name | The Name of the Internet Gateway | `string` | `"Free Tier Internet Gateway"` |
11 | | should\_be\_created | Should the Internet Gateway be created? | `bool` | `true` |
12 | | vpc\_id | The ID of the VPC | `string` | n/a |
13 |
14 | ### Outputs
15 |
16 | | Name | Description |
17 | |------|-------------|
18 | | id | The ID of the Internet Gateway |
19 |
20 |
--------------------------------------------------------------------------------
/modules/aws/gateway/main.tf:
--------------------------------------------------------------------------------
1 | resource "aws_internet_gateway" "internet_gateway" {
2 | vpc_id = var.vpc_id
3 |
4 | tags = {
5 | Name = var.name
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/modules/aws/gateway/outputs.tf:
--------------------------------------------------------------------------------
1 | output "id" {
2 | description = "The ID of the Internet Gateway"
3 | value = concat(aws_internet_gateway.internet_gateway.*.id, [""])[0]
4 | }
5 |
--------------------------------------------------------------------------------
/modules/aws/gateway/variables.tf:
--------------------------------------------------------------------------------
1 | variable "name" {
2 | description = "The Name of the Internet Gateway"
3 | type = string
4 | default = "Free Tier Internet Gateway"
5 | }
6 |
7 | variable "vpc_id" {
8 | description = "The ID of the VPC"
9 | sensitive = true
10 | type = string
11 | }
12 |
--------------------------------------------------------------------------------
/modules/aws/main.tf:
--------------------------------------------------------------------------------
1 | module "vpc" {
2 | source = "./vpc"
3 | region = var.region
4 | }
5 |
6 | module "ec2" {
7 | source = "./ec2"
8 | count = var.ec2_enable ? 1 : 0
9 |
10 | vpc_id = module.vpc.id
11 | public_subnet_id = module.vpc.public_subnets[0]
12 |
13 | ssh_name = var.ec2_ssh_name
14 | ssh_public = file(var.ec2_ssh_public)
15 | depends_on = [
16 | module.vpc.public_subnets
17 | ]
18 | }
19 |
20 | module "rds" {
21 | source = "./rds"
22 | count = var.rds_enable ? 1 : 0
23 |
24 | region = var.region
25 | vpc_id = module.vpc.id
26 | vpc_cidr_block = module.vpc.cidr_block
27 | vpc_subnet_ids = ["${module.vpc.database_subnets[0]}", "${module.vpc.database_subnets[1]}"]
28 | }
29 |
--------------------------------------------------------------------------------
/modules/aws/outputs.tf:
--------------------------------------------------------------------------------
1 | output "ec2_public_ip" {
2 | description = "List of public IP addresses assigned to the instances, if applicable"
3 | value = module.ec2.*.public_ip
4 | sensitive = true
5 | }
6 |
7 | output "ec2_ipv6_addresses" {
8 | description = "List of assigned IPv6 addresses of instances"
9 | value = module.ec2.*.ipv6_addresses
10 | sensitive = true
11 | }
12 |
13 | output "ec2_private_ip" {
14 | description = "List of private IP addresses assigned to the instances"
15 | value = module.ec2.*.private_ip
16 | sensitive = true
17 | }
18 |
19 | output "ec2_password_data" {
20 | description = "List of Base-64 encoded encrypted password data for the instance"
21 | value = module.ec2.*.password_data
22 | sensitive = true
23 | }
24 |
25 | output "ec2_key_name" {
26 | description = "List of key names of instances"
27 | value = module.ec2.*.names
28 | sensitive = true
29 | }
30 |
31 | output "db_id" {
32 | description = "List of key names of instances"
33 | value = module.rds.*.db_default_instance_id
34 | sensitive = true
35 | }
36 |
--------------------------------------------------------------------------------
/modules/aws/rds/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | | Name | Source | Version |
5 | |------|--------|---------|
6 | | db\_default | terraform-aws-modules/rds/aws | n/a |
7 | | security\_group | terraform-aws-modules/security-group/aws | n/a |
8 |
9 | ### Inputs
10 |
11 | | Name | Description | Type | Default |
12 | |------|-------------|------|---------|
13 | | db\_engine | The local path to the SSH Public Key | `string` | `"postgres"` |
14 | | db\_family | The local path to the SSH Public Key | `string` | `"postgres12"` |
15 | | db\_instance\_type | Instance type for database | `string` | `"db.t2.micro"` |
16 | | db\_major\_engine | n/a | `string` | `"12"` |
17 | | db\_name | n/a | `string` | `"newtable"` |
18 | | db\_password | Region for AWS resources | `string` | `"forALEKkjkfeajme"` |
19 | | db\_security\_group\_name | Instance type for database | `string` | `"security-db"` |
20 | | db\_user | Region for AWS resources | `string` | `"defaultuser"` |
21 | | db\_version | The SSH Key Name | `string` | `"12.6"` |
22 | | disk\_size | n/a | `number` | `20` |
23 | | license | Region for AWS resources | `string` | `"postgresql-license"` |
24 | | name | Region for AWS resources | `string` | `"databasetf"` |
25 | | region | n/a | `string` | n/a |
26 | | subnet\_group\_name | Instance type for database | `string` | `"subnet-db"` |
27 | | vpc\_cidr\_block | n/a | `string` | n/a |
28 | | vpc\_id | n/a | `string` | n/a |
29 | | vpc\_subnet\_ids | n/a | `any` | n/a |
30 |
31 | ### Outputs
32 |
33 | | Name | Description |
34 | |------|-------------|
35 | | db\_default\_instance\_address | The address of the RDS instance |
36 | | db\_default\_instance\_arn | The ARN of the RDS instance |
37 | | db\_default\_instance\_availability\_zone | The availability zone of the RDS instance |
38 | | db\_default\_instance\_endpoint | The connection endpoint |
39 | | db\_default\_instance\_hosted\_zone\_id | The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record) |
40 | | db\_default\_instance\_id | The RDS instance ID |
41 | | db\_default\_instance\_name | The database name |
42 | | db\_default\_instance\_port | The database port |
43 | | db\_default\_instance\_resource\_id | The RDS Resource ID of this instance |
44 | | db\_default\_instance\_status | The RDS instance status |
45 | | db\_default\_parameter\_group\_arn | The ARN of the db parameter group |
46 | | db\_default\_parameter\_group\_id | The db parameter group id |
47 | | db\_default\_subnet\_group\_arn | The ARN of the db subnet group |
48 | | db\_default\_subnet\_group\_id | The db subnet group name |
49 |
50 |
--------------------------------------------------------------------------------
/modules/aws/rds/main.tf:
--------------------------------------------------------------------------------
1 |
2 | module "security_group" {
3 | source = "terraform-aws-modules/security-group/aws"
4 |
5 | name = var.name
6 | description = "Complete PostgreSQL example security group"
7 | vpc_id = var.vpc_id
8 |
9 | # ingress
10 | ingress_with_cidr_blocks = [
11 | {
12 | from_port = 5432
13 | to_port = 5432
14 | protocol = "tcp"
15 | description = "PostgreSQL access from within VPC"
16 | cidr_blocks = var.vpc_cidr_block
17 | },
18 | ]
19 | }
20 |
21 | module "db_default" {
22 | source = "terraform-aws-modules/rds/aws"
23 |
24 | identifier = "${var.name}-default"
25 |
26 | create_db_option_group = false
27 | create_db_parameter_group = false
28 |
29 | # All available versions: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts
30 | engine = var.db_engine
31 | engine_version = var.db_version
32 | family = var.db_family # DB parameter group
33 | major_engine_version = var.db_major_engine # DB option group
34 | instance_class = var.db_instance_type
35 |
36 | allocated_storage = var.disk_size
37 |
38 | # NOTE: Do NOT use 'user' as the value for 'username' as it throws:
39 | # "Error creating DB Instance: InvalidParameterValue: MasterUsername
40 | # user cannot be used as it is a reserved word used by the engine"
41 | db_name = "${var.db_name}"
42 | username = var.db_user
43 | create_random_password = true
44 | random_password_length = 12
45 | port = 5432
46 |
47 | subnet_ids = var.vpc_subnet_ids
48 | vpc_security_group_ids = [module.security_group.security_group_id]
49 |
50 | maintenance_window = "Mon:00:00-Mon:03:00"
51 | backup_window = "03:00-06:00"
52 |
53 | backup_retention_period = 0 // no backup
54 | }
55 |
--------------------------------------------------------------------------------
/modules/aws/rds/outputs.tf:
--------------------------------------------------------------------------------
1 |
2 | # Default
3 | output "db_default_instance_address" {
4 | description = "The address of the RDS instance"
5 | value = concat(module.db_default.*.db_instance_address, [""])[0]
6 | }
7 |
8 | output "db_default_instance_arn" {
9 | description = "The ARN of the RDS instance"
10 | value = concat(module.db_default.*.db_instance_arn, [""])[0]
11 | }
12 |
13 | output "db_default_instance_availability_zone" {
14 | description = "The availability zone of the RDS instance"
15 | value = concat(module.db_default.*.db_instance_availability_zone, [""])[0]
16 | }
17 |
18 | output "db_default_instance_endpoint" {
19 | description = "The connection endpoint"
20 | value = concat(module.db_default.*.db_instance_endpoint, [""])[0]
21 | }
22 |
23 | output "db_default_instance_hosted_zone_id" {
24 | description = "The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record)"
25 | value = concat(module.db_default.*.db_instance_hosted_zone_id, [""])[0]
26 | }
27 |
28 | output "db_default_instance_id" {
29 | description = "The RDS instance ID"
30 | value = concat(module.db_default.*.db_instance_id, [""])[0]
31 | }
32 |
33 | output "db_default_instance_resource_id" {
34 | description = "The RDS Resource ID of this instance"
35 | value = concat(module.db_default.*.db_instance_resource_id, [""])[0]
36 | }
37 |
38 | output "db_default_instance_status" {
39 | description = "The RDS instance status"
40 | value = concat(module.db_default.*.db_instance_status, [""])[0]
41 | }
42 |
43 | output "db_default_instance_name" {
44 | description = "The database name"
45 | value = concat(module.db_default.*.db_instance_name, [""])[0]
46 | }
47 |
48 | output "db_default_instance_port" {
49 | description = "The database port"
50 | value = concat(module.db_default.*.db_instance_port, [""])[0]
51 | }
52 |
53 | output "db_default_subnet_group_id" {
54 | description = "The db subnet group name"
55 | value = concat(module.db_default.*.db_subnet_group_id, [""])[0]
56 | }
57 |
58 | output "db_default_subnet_group_arn" {
59 | description = "The ARN of the db subnet group"
60 | value = concat(module.db_default.*.db_subnet_group_arn, [""])[0]
61 | }
62 |
63 | output "db_default_parameter_group_id" {
64 | description = "The db parameter group id"
65 | value = concat(module.db_default.*.db_parameter_group_id, [""])[0]
66 | }
67 |
68 | output "db_default_parameter_group_arn" {
69 | description = "The ARN of the db parameter group"
70 | value = concat(module.db_default.*.db_parameter_group_arn, [""])[0]
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/modules/aws/rds/variables.tf:
--------------------------------------------------------------------------------
1 | variable "name" {
2 | description = "Region for AWS resources"
3 | type = string
4 | default = "databasetf"
5 | }
6 |
7 | variable "db_version" {
8 | description = "The SSH Key Name"
9 | type = string
10 | default = "12.6"
11 | }
12 |
13 | variable "db_family" {
14 | description = "The local path to the SSH Public Key"
15 | type = string
16 | default = "postgres12"
17 | }
18 |
19 | variable "db_major_engine" {
20 | type = string
21 | default = "12"
22 | }
23 |
24 | variable "db_engine" {
25 | description = "The local path to the SSH Public Key"
26 | type = string
27 | default = "postgres"
28 | }
29 |
30 | variable "disk_size" {
31 | type = number
32 | default = 20
33 | }
34 |
35 | variable "db_user" {
36 | description = "Region for AWS resources"
37 | default = "defaultuser"
38 | sensitive = true
39 | type = string
40 | }
41 |
42 | variable "db_password" {
43 | description = "Region for AWS resources"
44 | sensitive = true
45 | default = "forALEKkjkfeajme"
46 | type = string
47 | }
48 |
49 |
50 | variable "license" {
51 | description = "Region for AWS resources"
52 | default = "postgresql-license"
53 | type = string
54 | }
55 |
56 | variable "db_instance_type" {
57 | description = "Instance type for database"
58 | type = string
59 | default = "db.t2.micro"
60 | }
61 |
62 | variable "subnet_group_name" {
63 | description = "Instance type for database"
64 | sensitive = true
65 | type = string
66 | default = "subnet-db"
67 | }
68 |
69 |
70 | variable "db_security_group_name" {
71 | description = "Instance type for database"
72 | type = string
73 | sensitive = true
74 | default = "security-db"
75 | }
76 |
77 | variable "region" {
78 | type = string
79 | }
80 |
81 | variable "db_name" {
82 | type = string
83 | default = "newtable"
84 | }
85 |
86 | variable "vpc_id" {
87 | type = string
88 | }
89 |
90 | variable "vpc_cidr_block" {
91 | type = string
92 | }
93 |
94 | variable "vpc_subnet_ids" {
95 | }
96 |
--------------------------------------------------------------------------------
/modules/aws/variables.tf:
--------------------------------------------------------------------------------
1 | variable "profile" {
2 | description = "AWS Profile"
3 | type = string
4 | default = "terraform"
5 | }
6 |
7 | variable "region" {
8 | description = "Region for AWS resources"
9 | type = string
10 | default = "us-east-1"
11 | }
12 |
13 | variable "ec2_enable" {
14 | description = "AWS Profile"
15 | type = bool
16 | default = true
17 | }
18 |
19 | variable "rds_enable" {
20 | description = "AWS Profile"
21 | type = bool
22 | default = true
23 | }
24 |
25 | variable "ec2_ssh_name" {
26 | description = "The SSH Key Name"
27 | type = string
28 | default = "free-tier-ec2-key"
29 | }
30 |
31 | variable "ec2_ssh_public" {
32 | description = "The local path to the SSH Public Key"
33 | type = string
34 | sensitive = true
35 | default = "~/.ssh-temp/id_rsa.pub"
36 | }
37 |
38 | variable "rds_user" {
39 | description = "Region for AWS resources"
40 | type = string
41 | sensitive = true
42 | default = "testing"
43 | }
44 |
45 | variable "rds_password" {
46 | description = "Region for the RDS database"
47 | type = string
48 | sensitive = true
49 | default = "testingdatabase89372934279"
50 | }
51 |
--------------------------------------------------------------------------------
/modules/aws/vpc/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | | Name | Source | Version |
5 | |------|--------|---------|
6 | | vpc | terraform-aws-modules/vpc/aws | n/a |
7 |
8 | ### Inputs
9 |
10 | | Name | Description | Type | Default |
11 | |------|-------------|------|---------|
12 | | cidr | n/a | `string` | `"10.99"` |
13 | | db\_group\_create | n/a | `bool` | `true` |
14 | | name | Region for AWS resources | `string` | `"main-vpc"` |
15 | | nat | n/a | `bool` | `true` |
16 | | region | Region for AWS resources | `string` | n/a |
17 | | vpn | n/a | `bool` | `true` |
18 |
19 | ### Outputs
20 |
21 | | Name | Description |
22 | |------|-------------|
23 | | cidr\_block | n/a |
24 | | database\_subnets | n/a |
25 | | id | n/a |
26 | | public\_subnets | n/a |
27 |
--------------------------------------------------------------------------------
/modules/aws/vpc/main.tf:
--------------------------------------------------------------------------------
1 | module "vpc" {
2 | source = "terraform-aws-modules/vpc/aws"
3 |
4 | name = var.name
5 | cidr = "${var.cidr}.0.0/18"
6 |
7 | azs = ["${var.region}a", "${var.region}b", "${var.region}c"]
8 | public_subnets = ["${var.cidr}.0.0/24", "${var.cidr}.1.0/24", "${var.cidr}.2.0/24"]
9 | private_subnets = ["${var.cidr}.3.0/24", "${var.cidr}.4.0/24", "${var.cidr}.5.0/24"]
10 | database_subnets = ["${var.cidr}.7.0/24", "${var.cidr}.8.0/24", "${var.cidr}.9.0/24"]
11 |
12 | create_database_subnet_group = var.db_group_create
13 | enable_nat_gateway = var.nat
14 | enable_vpn_gateway = var.vpn
15 | }
16 |
--------------------------------------------------------------------------------
/modules/aws/vpc/outputs.tf:
--------------------------------------------------------------------------------
1 | output "id" {
2 | value = module.vpc.vpc_id
3 | }
4 | output "cidr_block" {
5 | value = module.vpc.vpc_cidr_block
6 | }
7 | output "database_subnets" {
8 | value = module.vpc.database_subnets
9 | }
10 | output "public_subnets" {
11 | value = module.vpc.public_subnets
12 | }
13 |
--------------------------------------------------------------------------------
/modules/aws/vpc/variables.tf:
--------------------------------------------------------------------------------
1 | variable "name" {
2 | description = "Region for AWS resources"
3 | type = string
4 | default = "main-vpc"
5 | }
6 |
7 | variable "cidr" {
8 | type = string
9 | default = "10.99" //10.99.0.0/18
10 | }
11 |
12 | variable "region" {
13 | description = "Region for AWS resources"
14 | type = string
15 | }
16 |
17 | variable "db_group_create" {
18 | type = bool
19 | default = true
20 | }
21 |
22 | variable "vpn" {
23 | type = bool
24 | default = true
25 | }
26 | variable "nat" {
27 | type = bool
28 | default = true
29 | }
--------------------------------------------------------------------------------
/modules/azure/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | | Name | Source | Version |
5 | |------|--------|---------|
6 | | compute | ./compute | n/a |
7 | | networking | ./vpc | n/a |
8 |
9 | ### Inputs
10 |
11 | | Name | Description | Type | Default |
12 | |------|-------------|------|---------|
13 | | database\_db\_name | n/a | `string` | `"mydatabase"` |
14 | | database\_name | n/a | `string` | `"myapp"` |
15 | | database\_password | n/a | `string` | `"P@ssw0rd12345!"` |
16 | | database\_user | n/a | `string` | `"mradministrator"` |
17 | | ldns\_server | n/a | `string` | `"uniquename"` |
18 | | linux\_name | n/a | `string` | `"linux-pc"` |
19 | | location | n/a | `string` | `"East US"` |
20 | | resource\_group\_name | n/a | `string` | `"my-azure-group"` |
21 | | wdns\_server | n/a | `string` | `"uniquename2"` |
22 | | windows\_name | n/a | `string` | `"windows-pc"` |
23 |
24 | ### Outputs
25 |
26 | No outputs.
27 |
28 |
--------------------------------------------------------------------------------
/modules/azure/compute/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | | Name | Source | Version |
5 | |------|--------|---------|
6 | | linuxservers | Azure/compute/azurerm | n/a |
7 | | windowsservers | Azure/compute/azurerm | n/a |
8 |
9 | ### Inputs
10 |
11 | | Name | Description | Type | Default |
12 | |------|-------------|------|---------|
13 | | linux\_dns\_server | n/a | `string` | `"linsimplevmips"` |
14 | | linux\_hostname | n/a | `string` | `"mywinvm"` |
15 | | linux\_password | n/a | `string` | `"mywinvj33j4k3"` |
16 | | resource\_group\_name | n/a | `string` | n/a |
17 | | subnet\_id | n/a | `string` | `"dev"` |
18 | | windows\_dns\_server | n/a | `string` | `"winsimplevmips"` |
19 | | windows\_hostname | n/a | `string` | `"mywinvm"` |
20 | | windows\_password | n/a | `string` | `"ComplxP@ssw0rd!"` |
21 |
22 | ### Outputs
23 |
24 | | Name | Description |
25 | |------|-------------|
26 | | linux\_vm\_public\_name | n/a |
27 | | windows\_vm\_public\_name | n/a |
28 |
29 |
--------------------------------------------------------------------------------
/modules/azure/compute/main.tf:
--------------------------------------------------------------------------------
1 | module "linuxservers" {
2 | source = "Azure/compute/azurerm"
3 | resource_group_name = var.resource_group_name
4 | vm_os_simple = "UbuntuServer"
5 | public_ip_dns = [var.linux_dns_server] // change to a unique name per datacenter region
6 | vnet_subnet_id = var.subnet_id //module.network.vnet_subnets[0]
7 |
8 | //depends_on = [azurerm_resource_group.example]
9 | }
10 |
11 | module "windowsservers" {
12 | source = "Azure/compute/azurerm"
13 | resource_group_name = var.resource_group_name
14 | is_windows_image = true
15 | vm_hostname = var.windows_hostname // line can be removed if only one VM module per resource group
16 | admin_password = var.windows_password
17 | vm_os_simple = "WindowsServer"
18 | public_ip_dns = [var.windows_dns_server] // change to a unique name per datacenter region
19 | vnet_subnet_id = var.subnet_id // module.network.vnet_subnets[0]
20 |
21 | //depends_on = [azurerm_resource_group.example]
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/modules/azure/compute/outputs.tf:
--------------------------------------------------------------------------------
1 | output "linux_vm_public_name" {
2 | value = module.linuxservers.public_ip_dns_name
3 | }
4 |
5 | output "windows_vm_public_name" {
6 | value = module.windowsservers.public_ip_dns_name
7 | }
8 |
--------------------------------------------------------------------------------
/modules/azure/compute/variables.tf:
--------------------------------------------------------------------------------
1 | variable "windows_password" {
2 | type = string
3 | default = "ComplxP@ssw0rd!"
4 | }
5 |
6 | variable "windows_hostname" {
7 | type = string
8 | default = "mywinvm"
9 | }
10 |
11 | variable "windows_dns_server" {
12 | type = string
13 | default = "winsimplevmips"
14 | }
15 |
16 | variable "linux_hostname" {
17 | type = string
18 | default = "mywinvm"
19 | }
20 |
21 | variable "linux_password" {
22 | type = string
23 | default = "mywinvj33j4k3"
24 | }
25 | variable "linux_dns_server" {
26 | type = string
27 | default = "linsimplevmips"
28 | }
29 |
30 | variable "subnet_id" {
31 | type = string
32 | default = "dev"
33 | }
34 |
35 | variable "resource_group_name" {
36 | type = string
37 | }
38 |
--------------------------------------------------------------------------------
/modules/azure/db/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | | Name | Source | Version |
5 | |------|--------|---------|
6 | | database | Azure/database/azurerm | n/a |
7 |
8 | ### Inputs
9 |
10 | | Name | Description | Type | Default |
11 | |------|-------------|------|---------|
12 | | db\_name | n/a | `string` | `"mydatabase"` |
13 | | location | n/a | `string` | `"westus"` |
14 | | name | n/a | `string` | `"myapp"` |
15 | | sql\_password | n/a | `string` | `"P@ssw0rd12345!"` |
16 | | sql\_user | n/a | `string` | `"mradministrator"` |
17 |
18 | ### Outputs
19 |
20 | | Name | Description |
21 | |------|-------------|
22 | | connection\_url | n/a |
23 | | sql\_name | n/a |
24 |
25 |
--------------------------------------------------------------------------------
/modules/azure/db/main.tf:
--------------------------------------------------------------------------------
1 | module "database" {
2 | source = "Azure/database/azurerm"
3 | resource_group_name = var.name
4 | location = var.location
5 | db_name = var.db_name
6 | sql_username = var.sql_user
7 | sql_password = var.sql_password
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/modules/azure/db/outputs.tf:
--------------------------------------------------------------------------------
1 |
2 | output "sql_name" {
3 | value = module.database.database_name
4 | }
5 |
6 | output "connection_url" {
7 | value = module.database.connection_string
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/modules/azure/db/variables.tf:
--------------------------------------------------------------------------------
1 | variable "name" {
2 | type = string
3 | default = "myapp"
4 | }
5 |
6 | variable "location" {
7 | type = string
8 | default = "westus"
9 | }
10 |
11 | variable "db_name" {
12 | type = string
13 | default = "mydatabase"
14 | }
15 |
16 | variable "sql_user" {
17 | type = string
18 | default = "mradministrator"
19 | }
20 |
21 | variable "sql_password" {
22 | type = string
23 | default = "P@ssw0rd12345!"
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/modules/azure/main.tf:
--------------------------------------------------------------------------------
1 |
2 | resource "azurerm_resource_group" "default" {
3 | name = var.resource_group_name
4 | location = var.location
5 | }
6 |
7 | module "networking" {
8 | depends_on = [azurerm_resource_group.default]
9 | resource_group_name = var.resource_group_name
10 | location = var.location
11 | source = "./vpc"
12 | }
13 |
14 | // module "database" {
15 | // source = "./db"
16 | // location = var.location
17 | // name = var.database_name
18 | // db_name = var.database_db_name
19 | // sql_username = var.database_user
20 | // depends_on = [
21 | // azurerm_resource_group.default,
22 | // networking.default
23 | // ]
24 | // }
25 |
26 | module "compute" {
27 | source = "./compute"
28 | resource_group_name = var.resource_group_name
29 | windows_hostname = var.windows_name
30 | linux_hostname = var.linux_name
31 | windows_dns_server = var.wdns_server
32 | linux_dns_server = var.ldns_server
33 | subnet_id = module.networking.vpc_id
34 | depends_on = [azurerm_resource_group.default]
35 | }
36 |
--------------------------------------------------------------------------------
/modules/azure/outputs.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/modules/azure/outputs.tf
--------------------------------------------------------------------------------
/modules/azure/variables.tf:
--------------------------------------------------------------------------------
1 | variable "resource_group_name" {
2 | type = string
3 | default = "my-azure-group"
4 | }
5 |
6 | variable "location" {
7 | type = string
8 | default = "East US"
9 | }
10 |
11 | variable "database_name" {
12 | type = string
13 | default = "myapp"
14 | }
15 |
16 | variable "database_db_name" {
17 | type = string
18 | default = "mydatabase"
19 | }
20 |
21 | variable "database_user" {
22 | type = string
23 | default = "mradministrator"
24 | }
25 |
26 | variable "database_password" {
27 | type = string
28 | default = "P@ssw0rd12345!"
29 | }
30 |
31 | variable "ldns_server" {
32 | type = string
33 | default = "uniquename"
34 | }
35 |
36 | variable "wdns_server" {
37 | type = string
38 | default = "uniquename2"
39 | }
40 |
41 | variable "windows_name" {
42 | type = string
43 | default = "windows-pc"
44 | }
45 |
46 | variable "linux_name" {
47 | type = string
48 | default = "linux-pc"
49 | }
--------------------------------------------------------------------------------
/modules/azure/vpc/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | No modules.
5 |
6 | ### Inputs
7 |
8 | | Name | Description | Type | Default |
9 | |------|-------------|------|---------|
10 | | location | Azure's specific deployment location. [Azure Terraform Provider Docs](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group#location) | `string` | n/a |
11 | | resource\_group\_name | The name which should be used for a specific resource group. [Azure Terraform Provider Docs](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group#name) | `string` | n/a |
12 |
13 | ### Outputs
14 |
15 | | Name | Description |
16 | |------|-------------|
17 | | vpc\_id | The id of the newly created vNet |
18 | | vpc\_location | The location of the newly created vNet |
19 | | vpc\_name | The name of the newly created vNet |
20 | | vpc\_space | The address space of the newly created vNet |
21 |
22 |
--------------------------------------------------------------------------------
/modules/azure/vpc/main.tf:
--------------------------------------------------------------------------------
1 | resource "azurerm_virtual_network" "example" {
2 | name = "virtualNetwork1"
3 | location = var.location
4 | resource_group_name = var.resource_group_name
5 | address_space = ["10.0.0.0/16"]
6 | dns_servers = ["10.0.0.4", "10.0.0.5"]
7 | subnet {
8 | name = "subnet1"
9 | address_prefix = "10.0.1.0/24"
10 | }
11 | }
12 |
13 | resource "azurerm_network_security_group" "ssh" {
14 | name = "ssh"
15 | resource_group_name = var.resource_group_name
16 | location = var.location
17 | security_rule {
18 | name = "test123"
19 | priority = 100
20 | direction = "Inbound"
21 | access = "Allow"
22 | protocol = "Tcp"
23 | source_port_range = "*"
24 | destination_port_range = "22"
25 | source_address_prefix = "*"
26 | destination_address_prefix = "*"
27 | }
28 |
29 | }
30 |
31 | resource "azurerm_route_table" "example" {
32 | name = "MyRouteTable"
33 | resource_group_name = var.resource_group_name
34 | location = var.location
35 | }
36 |
37 | resource "azurerm_route" "example" {
38 | name = "acceptanceTestRoute1"
39 | resource_group_name = var.resource_group_name
40 | route_table_name = azurerm_route_table.example.name
41 | address_prefix = "10.1.0.0/16"
42 | next_hop_type = "vnetlocal"
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/modules/azure/vpc/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vpc_id" {
2 | description = "The id of the newly created vNet"
3 | value = azurerm_virtual_network.example.id
4 | }
5 |
6 | output "vpc_name" {
7 | description = "The name of the newly created vNet"
8 | value = azurerm_virtual_network.example.name
9 | }
10 |
11 | output "vpc_location" {
12 | description = "The location of the newly created vNet"
13 | value = azurerm_virtual_network.example.location
14 | }
15 |
16 | output "vpc_space" {
17 | description = "The address space of the newly created vNet"
18 | value = azurerm_virtual_network.example.address_space
19 | }
20 |
--------------------------------------------------------------------------------
/modules/azure/vpc/variables.tf:
--------------------------------------------------------------------------------
1 | variable "resource_group_name" {
2 | type = string
3 | description = "The name which should be used for a specific resource group. [Azure Terraform Provider Docs](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group#name)"
4 | }
5 |
6 | variable "location" {
7 | type = string
8 | description = "Azure's specific deployment location. [Azure Terraform Provider Docs](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group#location)"
9 | }
10 |
--------------------------------------------------------------------------------
/modules/gcp/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | | Name | Source | Version |
5 | |------|--------|---------|
6 | | gcp\_firewall | ./firewall | n/a |
7 | | gcp\_instance | ./compute | n/a |
8 | | gcp\_storage | ./storage | n/a |
9 | | gcp\_vpc | ./vpc | n/a |
10 |
11 | ### Inputs
12 |
13 | | Name | Description | Type | Default |
14 | |------|-------------|------|---------|
15 | | bucket\_name | Public name of your storage bucket on GCP. [Naming guidelines for Storage Buckets \| GCP Docs](https://cloud.google.com/storage/docs/naming-buckets) | `string` | `"averynoncommonbuck"` |
16 | | firestore\_name | Your instance's network on GCP. | `string` | `"firestore-db-1"` |
17 | | gcp\_project\_id | Google Cloud SDK project's ID number identifier. [Indetifying projects \| GCP Docs](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects) | `string` | n/a |
18 | | google\_project | n/a | `string` | `""` |
19 | | instance\_name | GCP Compute Instance Name. [Resource Naming Convention \| GCP Compute Docs](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"example-machine"` |
20 | | network\_name | Creates and names a VPC network. A VPC network is not the same as a GCP Subnetwork, see: [VPC Network Overview \| GCP Docs](https://cloud.google.com/vpc/docs/vpc#vpc_networks_and_subnets) | `string` | `"gcp-network2"` |
21 | | permissions | Your instance's network on GCP. | `string` | `"publicread"` |
22 | | project\_region | Identifier for default resource location based on GCP region naming convention. [Regions and Zones \| GCP Docs](https://cloud.google.com/compute/docs/regions-zones) | `string` | `"us-west1"` |
23 |
24 | ### Outputs
25 |
26 | | Name | Description |
27 | |------|-------------|
28 | | machine\_ip | n/a |
29 |
30 |
--------------------------------------------------------------------------------
/modules/gcp/compute/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | No modules.
5 |
6 | ### Inputs
7 |
8 | | Name | Description | Type | Default |
9 | |------|-------------|------|---------|
10 | | disk\_size | Allocated GB's of disk to your GCE instance | `number` | `30` |
11 | | disk\_type | Storage Disk Type. [GCP Official documentation](https://cloud.google.com/compute/docs/disks#disk-types) | `string` | `"pd-standard"` |
12 | | image | Image to initialize your GCE Instance, a full list of options [is available on GCP's official documentation](https://cloud.google.com/compute/docs/images) | `string` | `"debian-cloud/debian-10"` |
13 | | ip\_addr | The IP address that will be 1:1 mapped to the instance's network ip. If not given, one will be generated. [Docs Ref.](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#access_config) | `string` | `null` |
14 | | name | A name for GCP's Virtual Machine instance. [Naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"private"` |
15 | | network\_name | GCP Network Name. [Oficial GCP Documentation](https://cloud.google.com/compute/docs/machine-types) - [Terraform provider Documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#machine_type) | `string` | `"example-network"` |
16 | | region | Zone location of your instance, you can choose a region on [GCP's Official Documentation](https://cloud.google.com/compute/docs/regions-zones#available) - [Terraform provider documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#zone) | `string` | `"us-west1"` |
17 | | type | GCP Instance Machine type. [Oficial GCP Documentation](https://cloud.google.com/compute/docs/machine-types) - [Terraform provider Documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#machine_type) | `string` | `"e2-micro"` |
18 |
19 | ### Outputs
20 |
21 | | Name | Description |
22 | |------|-------------|
23 | | external\_ip | n/a |
24 | | instance\_id | n/a |
25 | | internal\_ip | n/a |
26 | | resulting\_name | n/a |
27 | | resulting\_type | n/a |
28 |
29 |
--------------------------------------------------------------------------------
/modules/gcp/compute/main.tf:
--------------------------------------------------------------------------------
1 | resource "google_compute_instance" "gcp_example" {
2 | name = var.name
3 | machine_type = var.type
4 | zone = "${var.region}-b"
5 |
6 | allow_stopping_for_update = true
7 |
8 | boot_disk {
9 | initialize_params {
10 | image = var.image
11 | size = var.disk_size
12 | type = var.disk_type
13 | }
14 | }
15 |
16 | network_interface {
17 | network = var.network_name
18 | access_config {
19 | nat_ip = var.ip_addr
20 | }
21 | }
22 | tags = [
23 | "web",
24 | "ssh"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/modules/gcp/compute/outputs.tf:
--------------------------------------------------------------------------------
1 | output "instance_id" {
2 | value = google_compute_instance.gcp_example.instance_id
3 | }
4 | output "internal_ip" {
5 | value = google_compute_instance.gcp_example.network_interface.0.network_ip
6 | sensitive = true
7 | }
8 | output "external_ip" {
9 | value = google_compute_instance.gcp_example.network_interface.0.access_config.0.nat_ip
10 | sensitive = true
11 | }
12 | output "resulting_name" {
13 | value = google_compute_instance.gcp_example.name
14 | sensitive = true
15 | }
16 | output "resulting_type" {
17 | value = google_compute_instance.gcp_example.machine_type
18 | sensitive = true
19 | }
20 |
--------------------------------------------------------------------------------
/modules/gcp/compute/variables.tf:
--------------------------------------------------------------------------------
1 | variable "name" {
2 | type = string
3 | default = "private"
4 | description = "A name for GCP's Virtual Machine instance. [Naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
5 | validation {
6 | condition = can(regex("^[a-z0-9][-a-z0-9]*[a-z0-9]$", var.name))
7 | error_message = "The instance name can contain only dashes, lowercase letters, and numbers. It must be at least 2 characters and can neither start nor end with a dash."
8 | }
9 | }
10 |
11 | variable "type" {
12 | type = string
13 | default = "e2-micro"
14 | description = "GCP Instance Machine type. [Oficial GCP Documentation](https://cloud.google.com/compute/docs/machine-types) - [Terraform provider Documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#machine_type)"
15 | validation {
16 | condition = var.type == "e2-micro"
17 | error_message = "Error: Only `e2-micro` instances are elligible for the free Tier on GCP. `f1-micro` were deprecated as of August 2021."
18 | }
19 | }
20 |
21 | variable "region" {
22 | type = string
23 | default = "us-west1"
24 | description = "Zone location of your instance, you can choose a region on [GCP's Official Documentation](https://cloud.google.com/compute/docs/regions-zones#available) - [Terraform provider documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#zone)"
25 | validation {
26 | condition = can(index(["us-west1", "us-central1", "us-east1"], var.region))
27 | error_message = "Error: Only U.S. regions are available for the free tier GCE instances."
28 | }
29 | }
30 |
31 | variable "image" {
32 | type = string
33 | default = "debian-cloud/debian-10"
34 | description = "Image to initialize your GCE Instance, a full list of options [is available on GCP's official documentation](https://cloud.google.com/compute/docs/images)"
35 | }
36 |
37 | variable "disk_size" {
38 | type = number
39 | default = 30
40 | description = "Allocated GB's of disk to your GCE instance"
41 | validation {
42 | condition = var.disk_size > 10 || var.disk_size < 30
43 | error_message = "Error: Minimum disk size is 10GB (for most Linux OS) and the Free tier maximum disk size is 30GB."
44 | }
45 | }
46 |
47 | variable "disk_type" {
48 | type = string
49 | default = "pd-standard"
50 | description = "Storage Disk Type. [GCP Official documentation](https://cloud.google.com/compute/docs/disks#disk-types)"
51 | validation {
52 | condition = var.disk_type == "pd-standard"
53 | error_message = "Error: Only Standard Persistent Disks ('pd-standard') are elligible for the free tier on GCP."
54 | }
55 | }
56 |
57 | variable "network_name" {
58 | type = string
59 | default = "example-network"
60 | description = "GCP Network Name. [Oficial GCP Documentation](https://cloud.google.com/compute/docs/machine-types) - [Terraform provider Documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#machine_type)"
61 | }
62 |
63 | variable "ip_addr" {
64 | type = string
65 | default = null
66 | sensitive = true
67 | description = "The IP address that will be 1:1 mapped to the instance's network ip. If not given, one will be generated. [Docs Ref.](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#access_config)"
68 | }
69 |
--------------------------------------------------------------------------------
/modules/gcp/firewall/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | No modules.
5 |
6 | ### Inputs
7 |
8 | | Name | Description | Type | Default |
9 | |------|-------------|------|---------|
10 | | firewall\_ssh\_name | A name for your firewall rule that allows access to the port 22, used for SSH connections. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"allow-ssh"` |
11 | | firewall\_web\_name | A name for your firewall rule that allows acces to both ports 80 and 443, used for common web applications. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"allow-web"` |
12 | | network\_name | Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"gcp-internal-network"` |
13 |
14 | ### Outputs
15 |
16 | No outputs.
17 |
18 |
--------------------------------------------------------------------------------
/modules/gcp/firewall/main.tf:
--------------------------------------------------------------------------------
1 | resource "google_compute_firewall" "allow_web" {
2 | name = var.firewall_web_name
3 | network = var.network_name
4 |
5 |
6 | allow {
7 | protocol = "tcp"
8 | ports = ["80", "443"]
9 | }
10 |
11 | source_ranges = ["0.0.0.0/0"]
12 | target_tags = ["web"]
13 | }
14 |
15 | resource "google_compute_firewall" "allow_ssh" {
16 | name = var.firewall_ssh_name
17 | network = var.network_name
18 |
19 | allow {
20 | protocol = "tcp"
21 | ports = ["22"]
22 | }
23 |
24 | source_ranges = ["0.0.0.0/0"]
25 | target_tags = ["ssh"]
26 | }
27 |
--------------------------------------------------------------------------------
/modules/gcp/firewall/outputs.tf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/modules/gcp/firewall/outputs.tf
--------------------------------------------------------------------------------
/modules/gcp/firewall/variables.tf:
--------------------------------------------------------------------------------
1 | variable "firewall_web_name" {
2 | type = string
3 | default = "allow-web"
4 | description = "A name for your firewall rule that allows acces to both ports 80 and 443, used for common web applications. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
5 | }
6 |
7 | variable "firewall_ssh_name" {
8 | type = string
9 | default = "allow-ssh"
10 | description = "A name for your firewall rule that allows access to the port 22, used for SSH connections. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
11 | }
12 |
13 | variable "network_name" {
14 | type = string
15 | sensitive = true
16 | default = "gcp-internal-network"
17 | description = "Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
18 | }
19 |
--------------------------------------------------------------------------------
/modules/gcp/main.tf:
--------------------------------------------------------------------------------
1 | module "gcp_vpc" {
2 | vpc_name = var.network_name
3 | source = "./vpc"
4 | google_project = var.gcp_project_id
5 | }
6 |
7 | module "gcp_firewall" {
8 | depends_on = [
9 | module.gcp_vpc.network_name
10 | ]
11 | source = "./firewall"
12 | network_name = module.gcp_vpc.network_name
13 | }
14 |
15 | module "gcp_instance" {
16 | depends_on = [
17 | module.gcp_vpc.network_name,
18 | module.gcp_vpc.ipv4_add
19 | ]
20 | source = "./compute"
21 | name = var.instance_name
22 | region = var.project_region
23 | network_name = module.gcp_vpc.network_name
24 | }
25 |
26 | module "gcp_storage" {
27 | depends_on = [
28 | module.gcp_vpc.network_name,
29 | module.gcp_instance.resulting_name,
30 | ]
31 | source = "./storage"
32 | region = var.project_region
33 | project_id = var.google_project
34 | name = var.bucket_name
35 | permissions = var.permissions
36 | firestore_name = var.firestore_name
37 | network_name = module.gcp_vpc.network_name
38 | }
39 |
--------------------------------------------------------------------------------
/modules/gcp/outputs.tf:
--------------------------------------------------------------------------------
1 | output "machine_ip" {
2 | value = module.gcp_instance.external_ip
3 | sensitive = true
4 | }
5 |
--------------------------------------------------------------------------------
/modules/gcp/storage/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | No modules.
5 |
6 | ### Inputs
7 |
8 | | Name | Description | Type | Default |
9 | |------|-------------|------|---------|
10 | | enable\_destroy | When deleting a bucket, this boolean option will delete all contained objects. If you try to delete a bucket that contains objects, Terraform will fail that run. | `bool` | `true` |
11 | | fire\_size | Your Firestore Database size in GB's. | `number` | `5` |
12 | | firestore\_name | Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"my-firestore"` |
13 | | name | Public name of your storage bucket on GCP. [Naming guidelines for Storage Buckets \| GCP Docs](https://cloud.google.com/storage/docs/naming-buckets) | `string` | `"regionaltftest"` |
14 | | network\_name | Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | n/a |
15 | | permissions | Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"publicread"` |
16 | | project\_id | Google Cloud SDK project's ID number identifier. [Indetifying projects \| GCP Docs](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects) | `string` | n/a |
17 | | region | Identifier for default resource location based on GCP region naming convention. [Regions and Zones \| GCP Docs](https://cloud.google.com/compute/docs/regions-zones) | `string` | `"us-west1"` |
18 | | storage\_class | [Storage Bucket Classes \| GCP Docs](https://cloud.google.com/storage/docs/storage-classes) \| [GCP Storage Classes on Terraform Provider](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/storage_bucket#storage_class) | `string` | `"STANDARD"` |
19 | | table\_name | Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"share1"` |
20 |
21 | ### Outputs
22 |
23 | | Name | Description |
24 | |------|-------------|
25 | | bucket\_name | Name of the GCS bucket that will receive the objects. |
26 |
27 |
--------------------------------------------------------------------------------
/modules/gcp/storage/main.tf:
--------------------------------------------------------------------------------
1 | data "google_project" "current" {
2 | project_id = var.project_id
3 | }
4 |
5 | locals {
6 | default_role_entities = [
7 | "OWNER:project-owners-${data.google_project.current.number}",
8 | "OWNER:project-editors-${data.google_project.current.number}",
9 | "READER:project-viewers-${data.google_project.current.number}",
10 | "READER:allUsers",
11 | ]
12 | }
13 |
14 | resource "google_storage_bucket" "default" {
15 | project = var.project_id
16 | name = var.name
17 | location = "US"
18 | storage_class = var.storage_class
19 | force_destroy = var.enable_destroy
20 | }
21 |
22 | resource "google_storage_bucket_acl" "default" {
23 | bucket = google_storage_bucket.default.name
24 | default_acl = var.permissions
25 | role_entity = local.default_role_entities
26 | }
27 |
28 | /* resource "google_filestore_instance" "instance" {
29 | provider = google-beta
30 | name = var.firestore_name
31 | zone = "${var.region}-b"
32 | tier = var.storage_class
33 |
34 | file_shares {
35 | capacity_gb = var.fire_size
36 | name = var.table_name
37 |
38 | nfs_export_options {
39 | ip_ranges = ["10.0.0.0/24"]
40 | access_mode = "READ_WRITE"
41 | squash_mode = "NO_ROOT_SQUASH"
42 | }
43 |
44 | nfs_export_options {
45 | ip_ranges = ["10.10.0.0/24"]
46 | access_mode = "READ_ONLY"
47 | squash_mode = "ROOT_SQUASH"
48 | anon_uid = 123
49 | anon_gid = 456
50 | }
51 | }
52 |
53 | networks {
54 | network = var.network_name
55 | modes = ["MODE_IPV4"]
56 | }
57 | }
58 | */
59 |
--------------------------------------------------------------------------------
/modules/gcp/storage/outputs.tf:
--------------------------------------------------------------------------------
1 | output "bucket_name" {
2 | description = "Name of the GCS bucket that will receive the objects."
3 | value = google_storage_bucket.default.name
4 | }
5 | /* output "firestore_id" {
6 | description = "Name of the GCS bucket that will receive the objects."
7 | value = google_filestore_instance.instance.id
8 | }
9 | */
10 |
--------------------------------------------------------------------------------
/modules/gcp/storage/variables.tf:
--------------------------------------------------------------------------------
1 | variable "project_id" {
2 | type = string
3 | sensitive = true
4 | description = "Google Cloud SDK project's ID number identifier. [Indetifying projects | GCP Docs](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects)"
5 | }
6 | variable "name" {
7 | type = string
8 | default = "regionaltftest"
9 | description = "Public name of your storage bucket on GCP. [Naming guidelines for Storage Buckets | GCP Docs](https://cloud.google.com/storage/docs/naming-buckets)"
10 | }
11 |
12 | variable "storage_class" {
13 | type = string
14 | default = "STANDARD"
15 | description = "[Storage Bucket Classes | GCP Docs](https://cloud.google.com/storage/docs/storage-classes) | [GCP Storage Classes on Terraform Provider](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/storage_bucket#storage_class)"
16 | }
17 |
18 | variable "enable_destroy" {
19 | type = bool
20 | default = true
21 | description = "When deleting a bucket, this boolean option will delete all contained objects. If you try to delete a bucket that contains objects, Terraform will fail that run."
22 | }
23 |
24 | variable "permissions" {
25 | type = string
26 | default = "publicread"
27 | description = "Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
28 | }
29 |
30 | variable "firestore_name" {
31 | type = string
32 | default = "my-firestore"
33 | description = "Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
34 | }
35 |
36 | variable "region" {
37 | type = string
38 | default = "us-west1"
39 | description = "Identifier for default resource location based on GCP region naming convention. [Regions and Zones | GCP Docs](https://cloud.google.com/compute/docs/regions-zones)"
40 | }
41 |
42 | variable "fire_size" {
43 | type = number
44 | default = 5
45 | description = "Your Firestore Database size in GB's."
46 | }
47 |
48 | variable "table_name" {
49 | type = string
50 | default = "share1"
51 | description = "Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
52 | }
53 |
54 | variable "network_name" {
55 | type = string
56 | description = "Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
57 | }
58 |
--------------------------------------------------------------------------------
/modules/gcp/variables.tf:
--------------------------------------------------------------------------------
1 | variable "google_project" {
2 | type = string
3 | default = ""
4 | }
5 |
6 | variable "gcp_project_id" {
7 | description = "Google Cloud SDK project's ID number identifier. [Indetifying projects | GCP Docs](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects)"
8 | type = string
9 | sensitive = true
10 | }
11 |
12 | variable "instance_name" {
13 | type = string
14 | default = "example-machine"
15 | description = "GCP Compute Instance Name. [Resource Naming Convention | GCP Compute Docs](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
16 | }
17 |
18 | variable "project_region" {
19 | type = string
20 | default = "us-west1"
21 | description = "Identifier for default resource location based on GCP region naming convention. [Regions and Zones | GCP Docs](https://cloud.google.com/compute/docs/regions-zones)"
22 | }
23 |
24 | variable "network_name" {
25 | type = string
26 | default = "gcp-network2"
27 | description = "Creates and names a VPC network. A VPC network is not the same as a GCP Subnetwork, see: [VPC Network Overview | GCP Docs](https://cloud.google.com/vpc/docs/vpc#vpc_networks_and_subnets)"
28 | }
29 |
30 | variable "bucket_name" {
31 | type = string
32 | default = "averynoncommonbuck"
33 | description = "Public name of your storage bucket on GCP. [Naming guidelines for Storage Buckets | GCP Docs](https://cloud.google.com/storage/docs/naming-buckets)"
34 | }
35 |
36 | variable "permissions" {
37 | type = string
38 | default = "publicread"
39 | description = "Your instance's network on GCP."
40 | }
41 |
42 | variable "firestore_name" {
43 | type = string
44 | default = "firestore-db-1"
45 | description = "Your instance's network on GCP."
46 | }
47 |
--------------------------------------------------------------------------------
/modules/gcp/vpc/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Modules
3 |
4 | No modules.
5 |
6 | ### Inputs
7 |
8 | | Name | Description | Type | Default |
9 | |------|-------------|------|---------|
10 | | google\_project | Your static IP network resource name on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | n/a |
11 | | vpc\_name | Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format) | `string` | `"gcp-internal-network"` |
12 |
13 | ### Outputs
14 |
15 | | Name | Description |
16 | |------|-------------|
17 | | network\_name | n/a |
18 |
19 |
--------------------------------------------------------------------------------
/modules/gcp/vpc/main.tf:
--------------------------------------------------------------------------------
1 |
2 | resource "google_compute_network" "default" {
3 | name = var.vpc_name
4 | auto_create_subnetworks = "true"
5 | project = var.google_project
6 | }
7 |
8 | output "network_name" {
9 | value = google_compute_network.default.name
10 | }
11 |
--------------------------------------------------------------------------------
/modules/gcp/vpc/variables.tf:
--------------------------------------------------------------------------------
1 | variable "vpc_name" {
2 | type = string
3 | default = "gcp-internal-network"
4 | description = "Your instance's network on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
5 | }
6 |
7 | variable "google_project" {
8 | type = string
9 | description = "Your static IP network resource name on GCP. [GCP's Official documentation on naming resources](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
10 | }
11 |
--------------------------------------------------------------------------------
/outputs.tf:
--------------------------------------------------------------------------------
1 | output "s3_backend_domain" {
2 | value = module.terraform_state_backend.s3_bucket_domain_name
3 | description = "Domain name of the S3 bucket created on AWS as part of the backend infrastructure"
4 | sensitive = true
5 | }
6 |
7 | output "s3_backend_bucket" {
8 | description = "ID of the resulting S3 bucket created on AWS as part of the backend infrastructure"
9 | value = module.terraform_state_backend.s3_bucket_id
10 | sensitive = true
11 | }
12 |
13 | output "db_backend_name" {
14 | description = "Name of the resulting DynamoDB created for locking state files."
15 | value = module.terraform_state_backend.dynamodb_table_name
16 | sensitive = true
17 | }
18 |
19 | output "gcp_public_ip" {
20 | description = "GCP VM Compute IPv4 Public Address"
21 | value = module.google_cloud.machine_ip
22 | sensitive = true
23 | }
24 |
25 | output "aws_ec2_public_ip" {
26 | description = "AWS EC2 IPv4 Public Address"
27 | value = module.aws.ec2_public_ip
28 | sensitive = true
29 | }
30 |
31 | output "aws_ec2_ipv6_addresses" {
32 | description = "AWS EC2 IPv6 Public Address"
33 | value = module.aws.ec2_ipv6_addresses
34 | sensitive = true
35 | }
36 |
37 | output "aws_ec2_private_ip" {
38 | description = "AWS EC2 assigned Private IP"
39 | value = module.aws.ec2_private_ip
40 | sensitive = true
41 | }
42 |
43 | output "aws_ec2_password_data" {
44 | description = "List of Base-64 encoded encrypted password data for AWS EC2 instances"
45 | value = module.aws.ec2_password_data
46 | sensitive = true
47 | }
48 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/scripts/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | mkdir -p ~/.ssh
3 | chmod 700 ~/.ssh
4 | echo -e "Host *\n\tStrictHostKeyChecking no\n\tIdentityFile ~/ssh_key\n\n" > ~/.ssh/config
5 | ssh-keygen -t rsa -b 4096 -C "${GITHUB_EMAIL}" -N '${GITHUB_USER}' -f /root/.ssh/id_rsa
6 | git config --global url.'https://${GITHUB_USER}:${GITHUB_KEY}@github.com'.insteadOf 'https://github.com'
7 |
8 | if [ -f ~/.gcloud/credentials.json ]; then
9 | export GOOGLE_APPLICATION_CREDENTIALS=~/.gcloud/credentials.json
10 | fi
11 | if [ -f /project/credentials/gcp.json ]; then
12 | export GOOGLE_APPLICATION_CREDENTIALS=/project/credentials/gcp.json
13 | fi
14 | export GOOGLE_PROJECT=$GCP_PROJECT_ID
15 | #exec ./bin "$@"
16 | clear
17 | curl -sL https://git.io/_has | bash -s git tfscan \
18 | tfsec terraform-docs terraform go task
19 | exec "$@"
20 |
--------------------------------------------------------------------------------
/scripts/plan.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if echo "$AWS_DEFAULT_REGION" | grep -q "$AWS_DEFAULT_REGION"; then
3 | echo "Adding default region key"
4 | echo "aws_default_region = $AWS_DEAFULT_REGION" >> terraform.tfvars
5 | else
6 | echo "No region was set."
7 | fi
8 |
9 | if echo "$AWS_ACCOUNT_ID" | grep -q "$AWS_ACCOUNT_ID"; then
10 | echo "Adding AWS account ID"
11 | echo "aws_account_id = $AWS_ACCOUNT_ID" >> terraform.tfvars
12 | else
13 | echo "No account ID was set."
14 | fi
15 |
16 | if echo "$AWS_SECRET_ACCESS_KEY" | grep -q "$AWS_SECRET_ACCESS_KEY"; then
17 | echo "Adding secret account key"
18 | echo "aws_account_key = $AWS_SECRET_ACCESS_KEY" >> terraform.tfvars
19 | else
20 | echo "No secret key was set."
21 | fi
22 |
--------------------------------------------------------------------------------
/scripts/requirements.txt:
--------------------------------------------------------------------------------
1 | awscli==1.25.47
2 |
--------------------------------------------------------------------------------
/scripts/slim.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/scripts/slim.yml
--------------------------------------------------------------------------------
/scripts/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | echo "stdout: passed"
5 | >&2 echo -e "stderr: building error"
--------------------------------------------------------------------------------
/tasks/aws.yaml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | vars:
3 | PATH_ERROR: is not installed or correctly configured in PATH.
4 |
5 | silent: true
6 |
7 | tasks:
8 | init:
9 | desc: Bootstrapping AWS provider testing files
10 | cmds:
11 | - cd test/aws && rm go.mod || true
12 | - cd test/aws && rm go.sum || true
13 | - cd test/aws && go mod init "github.com/gruberdev/tf-free" && go mod tidy
14 |
15 | test:
16 | deps:
17 | - init
18 | desc: Terraform testing (AWS provider)
19 | cmds:
20 | - cd test/aws && go test -v -timeout 10m -run TestUnitEC2
21 | - cd test/aws && go test -v -timeout 10m -run TestUnitRDS
22 |
23 | test:unit:ec2:
24 | deps:
25 | - aws-init
26 | cmds:
27 | - cd test/aws && go test -v -timeout 15m -run TestUnitEC2
28 |
29 | test:unit:rds:
30 | deps:
31 | - aws-init
32 | cmds:
33 | - cd test/aws && go test -v -timeout 30m -run TestUnitRDS
34 |
35 | apply:
36 | desc: Terraform standard initialization
37 | cmds:
38 | - cd modules/aws && terraform apply -auto-approve
39 |
40 | destroy:db:
41 | desc: Terraform standard initialization
42 | cmds:
43 | - terraform destroy -target module.aws.module.rds.aws_db_instance.rds -auto-approve
44 |
--------------------------------------------------------------------------------
/tasks/clean.yaml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | vars:
3 | PATH_ERROR: is not installed or correctly configured in PATH.
4 |
5 | silent: true
6 |
7 | tasks:
8 | aws:
9 | env:
10 | AWS_DEFAULT_REGION: "us-east-1"
11 | preconditions:
12 | - sh: 'which awsweeper'
13 | msg: 'kustomize {{.PATH_ERROR}}'
14 | cmds:
15 | - awsweeper config/aws-filter.yaml
16 | silent: true
17 |
18 | gcp:
19 | preconditions:
20 | - sh: 'which gcloud'
21 | msg: 'kustomize {{.PATH_ERROR}}'
22 | cmds:
23 | - docker run --rm --name cloudblaster -w /config -v ./config:/config docker.io/grubertech/cloudblaster:0.1
24 | silent: true
25 |
--------------------------------------------------------------------------------
/tasks/docker.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gruberdev/tf-free/c0311e73485e8f151172cbf97a25b1c52a28676a/tasks/docker.yaml
--------------------------------------------------------------------------------
/tasks/gcp.yaml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | vars:
3 | PATH_ERROR: is not installed or correctly configured in PATH.
4 |
5 | silent: true
6 |
7 | tasks:
8 | init:test:
9 | desc: test
10 | cmds:
11 | - cd test/gcp && rm go.mod || true
12 | - cd test/gcp && rm go.sum || true
13 | - cd test/gcp && go mod init "github.com/gruberdev/tf-free" || true
14 | - cd test/gcp && go mod tidy || true
15 |
16 | test:
17 | desc: Terraform testing (GCP provider)
18 | deps:
19 | - task: init:test
20 | - task: init
21 | - task: test:unit:network
22 | - task: test:unit:compute
23 | - task: test:unit:storage
24 | cmds:
25 | - cd test/gcp && go test -v -timeout 10m -run TestIntegrationGCP
26 |
27 | test:unit:compute:
28 | deps:
29 | - init
30 | cmds:
31 | - cd test/gcp && go test -v -timeout 5m -run TestUnitCompute
32 |
33 | test:unit:storage:
34 | deps:
35 | - init
36 | cmds:
37 | - cd test/gcp && go test -v -timeout 5m -run TestUnitStorage
38 |
39 | test:unit:network:
40 | deps:
41 | - init
42 | cmds:
43 | - cd test/gcp && go test -v -timeout 5m -run TestUnitVPC
44 |
45 | apply:
46 | desc: Terraform standard initialization
47 | cmds:
48 | - cd modules/gcp && terraform apply -auto-approve
49 |
50 | destroy:
51 | desc: Terraform standard initialization
52 | cmds:
53 | - cd modules/gcp && terraform destroy -auto-approve
54 |
55 | init:
56 | desc: Login into Google Cloud Platform
57 | cmds:
58 | - gcloud auth application-default login
59 |
--------------------------------------------------------------------------------
/test/aws/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Requirements
3 |
4 | No requirements.
5 |
6 | ## Providers
7 |
8 | No providers.
9 |
10 | ## Modules
11 |
12 | No modules.
13 |
14 | ## Resources
15 |
16 | No resources.
17 |
18 | ## Inputs
19 |
20 | No inputs.
21 |
22 | ## Outputs
23 |
24 | No outputs.
25 |
--------------------------------------------------------------------------------
/test/aws/ec2_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | "time"
7 |
8 | "github.com/gruntwork-io/terratest/modules/aws"
9 | "github.com/gruntwork-io/terratest/modules/environment"
10 | http_helper "github.com/gruntwork-io/terratest/modules/http-helper"
11 | "github.com/gruntwork-io/terratest/modules/random"
12 | "github.com/gruntwork-io/terratest/modules/ssh"
13 | "github.com/gruntwork-io/terratest/modules/terraform"
14 | )
15 |
16 | var accessList = []string{
17 | "AWS_ACCESS_KEY_ID",
18 | }
19 |
20 | var secretList = []string{
21 | "AWS_SECRET_ACCESS_KEY",
22 | }
23 |
24 | func TestUnitEC2(t *testing.T) {
25 | t.Parallel()
26 | sshName := fmt.Sprintf("ssh-key-%s", random.UniqueId())
27 | // Pick a random AWS region to test in. This helps ensure your code works in all regions.
28 | awsRegion := aws.GetRandomStableRegion(t, []string{"us-east-1"}, nil)
29 | awsAvailability := aws.GetAvailabilityZones(t, awsRegion)
30 | awsAccessID := environment.GetFirstNonEmptyEnvVarOrEmptyString(t, accessList)
31 | awsSecretKey := environment.GetFirstNonEmptyEnvVarOrEmptyString(t, secretList)
32 | // retryable errors in terraform testing.
33 | keyPair := ssh.GenerateRSAKeyPair(t, 2048)
34 | amiID := aws.GetUbuntu1604Ami(t, awsRegion)
35 | keyPublic := fmt.Sprintf("%s", keyPair.PublicKey)
36 | terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
37 | // website::tag::1:: The path to where our Terraform code is located
38 | TerraformDir: "../../examples/aws/unit/ec2",
39 | // Environment variables to set when running Terraform
40 | Vars: map[string]interface{}{
41 | "aws_default_region": awsRegion,
42 | "ssh_name": sshName,
43 | "ssh_public": keyPublic,
44 | "subnet_region": awsAvailability[0],
45 | "ami_id": amiID,
46 | },
47 | EnvVars: map[string]string{
48 | "AWS_DEFAULT_REGION": awsRegion,
49 | "AWS_ACCESS_KEY_ID": awsAccessID,
50 | "AWS_SECRET_ACCESS_KEY": awsSecretKey,
51 | },
52 | })
53 |
54 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
55 | defer terraform.Destroy(t, terraformOptions)
56 |
57 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
58 | terraform.InitAndApply(t, terraformOptions)
59 | publicIp := terraform.Output(t, terraformOptions, "public_ip")
60 |
61 | // website::tag::5:: Make an HTTP request to the instance and make sure we get back a 200 OK with the body "Hello, World!"
62 | url := fmt.Sprintf("http://%s:80", publicIp)
63 | http_helper.HttpGetWithRetry(t, url, nil, 200, "Hello, World!", 30, 5*time.Second)
64 | }
65 |
--------------------------------------------------------------------------------
/test/aws/network_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/aws"
7 | "github.com/gruntwork-io/terratest/modules/terraform"
8 | "github.com/stretchr/testify/assert"
9 | "github.com/stretchr/testify/require"
10 | )
11 |
12 | // An example of how to test the Terraform module in examples/terraform-aws-network-example using Terratest.
13 | func TestUnitAWSNetworking(t *testing.T) {
14 | t.Parallel()
15 |
16 | // Pick a random AWS region to test in. This helps ensure your code works in all regions.
17 | awsRegion := aws.GetRandomStableRegion(t, nil, nil)
18 |
19 | // Give the VPC and the subnets correct CIDRs
20 | vpcCidr := "10.10.0.0/16"
21 | privateSubnetCidr := "10.10.1.0/24"
22 | publicSubnetCidr := "10.10.2.0/24"
23 |
24 | // Construct the terraform options with default retryable errors to handle the most common retryable errors in
25 | // terraform testing.
26 | terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
27 | // The path to where our Terraform code is located
28 | TerraformDir: "../examples/terraform-aws-network-example",
29 |
30 | // Variables to pass to our Terraform code using -var options
31 | Vars: map[string]interface{}{
32 | "main_vpc_cidr": vpcCidr,
33 | "private_subnet_cidr": privateSubnetCidr,
34 | "public_subnet_cidr": publicSubnetCidr,
35 | "aws_region": awsRegion,
36 | },
37 | })
38 |
39 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
40 | defer terraform.Destroy(t, terraformOptions)
41 |
42 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
43 | terraform.InitAndApply(t, terraformOptions)
44 |
45 | // Run `terraform output` to get the value of an output variable
46 | publicSubnetId := terraform.Output(t, terraformOptions, "public_subnet_id")
47 | privateSubnetId := terraform.Output(t, terraformOptions, "private_subnet_id")
48 | vpcId := terraform.Output(t, terraformOptions, "main_vpc_id")
49 |
50 | subnets := aws.GetSubnetsForVpc(t, vpcId, awsRegion)
51 |
52 | require.Equal(t, 2, len(subnets))
53 | // Verify if the network that is supposed to be public is really public
54 | assert.True(t, aws.IsPublicSubnet(t, publicSubnetId, awsRegion))
55 | // Verify if the network that is supposed to be private is really private
56 | assert.False(t, aws.IsPublicSubnet(t, privateSubnetId, awsRegion))
57 | }
58 |
--------------------------------------------------------------------------------
/test/aws/rds_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | "testing"
7 |
8 | "github.com/gruntwork-io/terratest/modules/aws"
9 | "github.com/gruntwork-io/terratest/modules/random"
10 | "github.com/gruntwork-io/terratest/modules/terraform"
11 | "github.com/stretchr/testify/assert"
12 | )
13 |
14 | // An example of how to test the Terraform module in examples/terraform-aws-rds-example using Terratest.
15 | func TestUnitRDS(t *testing.T) {
16 | t.Parallel()
17 |
18 | // Give this RDS Instance a unique ID for a name tag so we can distinguish it from any other RDS Instance running
19 | // in your AWS account
20 | expectedName := fmt.Sprintf("terratest-aws-rds-example-%s", strings.ToLower(random.UniqueId()))
21 | expectedPort := int64(5432)
22 | expectedDatabaseName := "terratest"
23 | username := "username"
24 | password := "password"
25 | // Pick a random AWS region to test in. This helps ensure your code works in all regions.
26 | awsRegion := aws.GetRandomStableRegion(t, []string{"us-east-1"}, nil)
27 | instanceType := aws.GetRecommendedRdsInstanceType(t, awsRegion, "postgres", "12.6", []string{"db.t2.micro", "db.t3.micro"})
28 |
29 | // Construct the terraform options with default retryable errors to handle the most common retryable errors in
30 | // terraform testing.
31 | terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
32 | // The path to where our Terraform code is located
33 | TerraformDir: "../../examples/aws/unit/rds",
34 |
35 | // Variables to pass to our Terraform code using -var options
36 | // "username" and "password" should not be passed from here in a production scenario.
37 | Vars: map[string]interface{}{
38 | "name": expectedName,
39 | "engine_name": "postgres",
40 | "engine_version": "12.6",
41 | "instance_class": instanceType,
42 | "username": username,
43 | "password": password,
44 | "allocated_storage": 5,
45 | "db_port": expectedPort,
46 | "database_name": expectedDatabaseName,
47 | "aws_default_region": awsRegion,
48 | },
49 |
50 | // Environment variables to set when running Terraform
51 | EnvVars: map[string]string{
52 | "AWS_DEFAULT_REGION": awsRegion,
53 | },
54 | })
55 |
56 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
57 | defer terraform.Destroy(t, terraformOptions)
58 |
59 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
60 | terraform.InitAndApply(t, terraformOptions)
61 | // // Run `terraform output` to get the value of an output variable
62 | // dbInstanceID := terraform.Output(t, terraformOptions, "db_id")
63 |
64 | // // Look up the endpoint address and port of the RDS instance
65 | // address := aws.GetAddressOfRdsInstance(t, dbInstanceID, awsRegion)
66 | // port := aws.GetPortOfRdsInstance(t, dbInstanceID, awsRegion)
67 | // // Lookup parameter values. All defined values are strings in the API call response
68 | // // Lookup option values. All defined values are strings in the API call response
69 | // // Verify that the address is not null
70 | // assert.NotNil(t, address)
71 | // // Verify that the DB instance is listening on the port mentioned
72 | // assert.Equal(t, expectedPort, port)
73 | dbInstanceID := terraform.Output(t, terraformOptions, "db_id")
74 | address := aws.GetAddressOfRdsInstance(t, dbInstanceID, awsRegion)
75 | port := aws.GetPortOfRdsInstance(t, dbInstanceID, awsRegion)
76 | assert.NotNil(t, address)
77 | // Verify that the DB instance is listening on the port mentioned
78 | assert.Equal(t, expectedPort, port)
79 | // Verify that the table/schema requested for creation is actually present in the database
80 | }
81 |
--------------------------------------------------------------------------------
/test/azure/azure_integrated_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/terraform"
7 | )
8 |
9 | func TestIntegrationAzure(t *testing.T) {
10 | t.Parallel()
11 |
12 | /* subscriptionID := ""
13 | uniquePostfix := random.UniqueId() */
14 |
15 | // Configure Terraform setting up a path to Terraform code.
16 | terraformOptions := &terraform.Options{
17 | // The path to where our Terraform code is located.
18 | TerraformDir: "../../examples/azure/e2e",
19 |
20 | // Variables to pass to our Terraform code using -var options.
21 | Vars: map[string]interface{}{
22 | "location": "eastus",
23 | "resource_group_name": "test",
24 | },
25 | }
26 |
27 | // At the end of the test, run `terraform destroy` to clean up any resources that were created.
28 | defer terraform.Destroy(t, terraformOptions)
29 |
30 | // Run `terraform init` and `terraform apply`. Fail the test if there are any errors.
31 | terraform.InitAndApply(t, terraformOptions)
32 |
33 | // Run tests for the Virtual Machine.
34 | }
35 |
36 | /* func testStrategiesForVMs(t *testing.T, terraformOptions *terraform.Options, subscriptionID string) {
37 | // Run `terraform output` to get the values of output variables.
38 | resourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name")
39 | virtualMachineName := terraform.Output(t, terraformOptions, "linux_name")
40 | expectedVMSize := compute.VirtualMachineSizeTypes(terraform.Output(t, terraformOptions, "vm_size"))
41 |
42 | // 1. Check the VM Size directly. This strategy gets one specific property of the VM per method.
43 | actualVMSize := azure.GetSizeOfVirtualMachine(t, virtualMachineName, resourceGroupName, subscriptionID)
44 | assert.Equal(t, expectedVMSize, actualVMSize)
45 |
46 | // 2. Check the VM size by reference. This strategy is beneficial when checking multiple properties
47 | // by using one VM reference. Optional parameters have to be checked first to avoid nil panics.
48 | vmByRef := azure.GetVirtualMachine(t, virtualMachineName, resourceGroupName, subscriptionID)
49 | actualVMSize = vmByRef.HardwareProfile.VMSize
50 | assert.Equal(t, expectedVMSize, actualVMSize)
51 |
52 | // 3. Check the VM size by instance. This strategy is beneficial when checking multiple properties
53 | // by using one VM instance and making calls against it with the added benefit of property check abstraction.
54 | vmInstance := azure.Instance{VirtualMachine: vmByRef}
55 | actualVMSize = vmInstance.GetVirtualMachineInstanceSize()
56 | assert.Equal(t, expectedVMSize, actualVMSize)
57 | }
58 | */
59 |
--------------------------------------------------------------------------------
/test/docker/dockerfile_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/docker"
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestDockerBuild(t *testing.T) {
11 | t.Parallel()
12 | dockerComposeFile := "../../deployments/test.yml"
13 | docker.RunDockerCompose(
14 | t,
15 | &docker.Options{},
16 | "-f",
17 | dockerComposeFile,
18 | "build",
19 | )
20 |
21 | output := docker.RunDockerComposeAndGetStdOut(
22 | t,
23 | &docker.Options{},
24 | "-f",
25 | dockerComposeFile,
26 | "run",
27 | "--rm",
28 | "simple_stdout",
29 | )
30 | assert.Contains(t, output, "stdout: passed")
31 | assert.NotContains(t, output, "stderr: building error")
32 | }
33 |
--------------------------------------------------------------------------------
/test/gcp/compute_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/gcp"
7 | "github.com/gruntwork-io/terratest/modules/terraform"
8 | test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
9 | "github.com/stretchr/testify/assert"
10 | )
11 |
12 | func TestUnitCompute(t *testing.T) {
13 | t.Parallel()
14 |
15 | projectId := gcp.GetGoogleProjectIDFromEnvVar(t)
16 | gsCreds := gcp.GetGoogleCredentialsFromEnvVar(t)
17 | exampleDir := test_structure.CopyTerraformFolderToTemp(t, "../../", "examples/gcp/unit/compute")
18 | region := gcp.GetRandomRegion(t, projectId, []string{"us-west1", "us-central1", "us-east1"}, nil)
19 | randomValidGcpName := gcp.RandomValidGcpName()
20 | terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
21 | TerraformDir: exampleDir,
22 | Vars: map[string]interface{}{
23 | "gcp_project_region": region,
24 | "gcp_instance_name": randomValidGcpName,
25 | "gcp_project_id": projectId,
26 | },
27 | EnvVars: map[string]string{
28 | "GOOGLE_PROJECT": projectId,
29 | "GOOGLE_APPLICATION_CREDENTIALS": gsCreds,
30 | },
31 | })
32 |
33 | defer terraform.Destroy(t, terraformOptions)
34 | terraform.InitAndApply(t, terraformOptions)
35 |
36 | resultingInstanceName := terraform.OutputRequired(t, terraformOptions, "resulting_name")
37 | resultingInstanceType := terraform.OutputRequired(t, terraformOptions, "resulting_type")
38 | assert.Equal(t, randomValidGcpName, resultingInstanceName)
39 | assert.Equal(t, "f1-micro", resultingInstanceType)
40 | }
41 |
--------------------------------------------------------------------------------
/test/gcp/gcp_test.go:
--------------------------------------------------------------------------------
1 | // NOTE: We use build tags to differentiate GCP testing for better isolation and parallelism when executing our tests.
2 |
3 | package test
4 |
5 | import (
6 | "fmt"
7 | "strings"
8 | "testing"
9 | "time"
10 |
11 | "github.com/gruntwork-io/terratest/modules/gcp"
12 | "github.com/gruntwork-io/terratest/modules/retry"
13 | "github.com/gruntwork-io/terratest/modules/ssh"
14 | "github.com/gruntwork-io/terratest/modules/terraform"
15 | test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
16 | )
17 |
18 | func TestIntegrationGCP(t *testing.T) {
19 | t.Parallel()
20 |
21 | projectId := gcp.GetGoogleProjectIDFromEnvVar(t)
22 | exampleDir := test_structure.CopyTerraformFolderToTemp(t, "../../", "examples/gcp/e2e")
23 | region := gcp.GetRandomRegion(t, projectId, []string{"us-west1", "us-central1", "us-east1"}, nil)
24 | randomValidGcpName := gcp.RandomValidGcpName()
25 | randomValidNetworkGcpName := gcp.RandomValidGcpName()
26 | randomValidBucketGcpName := gcp.RandomValidGcpName()
27 | gsCreds := gcp.GetGoogleCredentialsFromEnvVar(t)
28 | // Variables to pass to our Terraform code using -var options
29 | terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
30 | // The path to where our Terraform code is located
31 | TerraformDir: exampleDir,
32 | Vars: map[string]interface{}{
33 | "gcp_project_region": region,
34 | "gcp_instance_name": randomValidGcpName,
35 | "gcp_network_name": randomValidNetworkGcpName,
36 | "gcp_bucket_name": randomValidBucketGcpName,
37 | "gcp_project_id": projectId,
38 | },
39 | EnvVars: map[string]string{
40 | "GOOGLE_PROJECT": projectId,
41 | "GOOGLE_APPLICATION_CREDENTIALS": gsCreds,
42 | },
43 | })
44 | defer terraform.Destroy(t, terraformOptions)
45 | terraform.InitAndApply(t, terraformOptions)
46 | publicIp := terraform.Output(t, terraformOptions, "gcp_public_ip")
47 | instance := gcp.FetchInstance(t, projectId, randomValidGcpName)
48 | sampleText := "Hello World"
49 | sshUsername := "root"
50 | keyPair := ssh.GenerateRSAKeyPair(t, 2048)
51 | instance.AddSshKey(t, sshUsername, keyPair.PublicKey)
52 | host := ssh.Host{
53 | Hostname: publicIp,
54 | SshKeyPair: keyPair,
55 | SshUserName: sshUsername,
56 | }
57 | maxRetries := 20
58 | sleepBetweenRetries := 4 * time.Second
59 | retry.DoWithRetry(t, "Attempting to SSH", maxRetries, sleepBetweenRetries, func() (string, error) {
60 | output, err := ssh.CheckSshCommandE(t, host, fmt.Sprintf("echo '%s'", sampleText))
61 | if err != nil {
62 | return "", err
63 | }
64 |
65 | if strings.TrimSpace(sampleText) != strings.TrimSpace(output) {
66 | return "", fmt.Errorf("Expected: %s. Got: %s\n", sampleText, output)
67 | }
68 |
69 | return "", nil
70 | })
71 | }
72 |
--------------------------------------------------------------------------------
/test/gcp/storage_test.go:
--------------------------------------------------------------------------------
1 | // NOTE: We use build tags to differentiate GCP testing for better isolation and parallelism when executing our tests.
2 |
3 | package test
4 |
5 | import (
6 | "bytes"
7 | "fmt"
8 | "strings"
9 | "testing"
10 |
11 | "github.com/gruntwork-io/terratest/modules/gcp"
12 | "github.com/gruntwork-io/terratest/modules/logger"
13 | "github.com/gruntwork-io/terratest/modules/random"
14 | "github.com/gruntwork-io/terratest/modules/terraform"
15 | test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
16 | "github.com/stretchr/testify/require"
17 | )
18 |
19 | func TestUnitStorage(t *testing.T) {
20 | t.Parallel()
21 |
22 | projectId := gcp.GetGoogleProjectIDFromEnvVar(t)
23 | gsCreds := gcp.GetGoogleCredentialsFromEnvVar(t)
24 | exampleDir := test_structure.CopyTerraformFolderToTemp(t, "../../", "examples/gcp/unit/storage")
25 | region := gcp.GetRandomRegion(t, projectId, []string{"us-east1"}, nil)
26 |
27 | gsNetworkName := gcp.RandomValidGcpName()
28 | gsBucketName := gcp.RandomValidGcpName()
29 |
30 | // Variables to pass to our Terraform code using -var options
31 | terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
32 | // The path to where our Terraform code is located
33 | TerraformDir: exampleDir,
34 | Vars: map[string]interface{}{
35 | "gcp_project_region": region,
36 | "gcp_network_name": gsNetworkName,
37 | "gcp_project_id": projectId,
38 | "gcp_bucket_name": gsBucketName,
39 | },
40 | EnvVars: map[string]string{
41 | "GOOGLE_PROJECT": projectId,
42 | "GOOGLE_APPLICATION_CREDENTIALS": gsCreds,
43 | },
44 | })
45 |
46 | defer terraform.Destroy(t, terraformOptions)
47 | terraform.InitAndApply(t, terraformOptions)
48 |
49 | testFilePath := fmt.Sprintf("test-file-%s.txt", random.UniqueId())
50 | testFileBody := "test file text"
51 | logger.Logf(t, "Random values selected Bucket Name = %s, Test Filepath: %s\n", gsBucketName, testFilePath)
52 | objectURL := gcp.WriteBucketObject(t, gsBucketName, testFilePath, strings.NewReader(testFileBody), "text/plain")
53 | logger.Logf(t, "Got URL: %s", objectURL)
54 | fileReader := gcp.ReadBucketObject(t, gsBucketName, testFilePath)
55 | buf := new(bytes.Buffer)
56 | buf.ReadFrom(fileReader)
57 | result := buf.String()
58 | require.Equal(t, testFileBody, result)
59 | }
60 |
--------------------------------------------------------------------------------
/test/gcp/vpc_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/gcp"
7 | "github.com/gruntwork-io/terratest/modules/terraform"
8 | test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
9 | )
10 |
11 | func TestUnitVPC(t *testing.T) {
12 | t.Parallel()
13 | randomValidNetworkGcpName := gcp.RandomValidGcpName()
14 | projectId := gcp.GetGoogleProjectIDFromEnvVar(t)
15 | gsCreds := gcp.GetGoogleCredentialsFromEnvVar(t)
16 | exampleDir := test_structure.CopyTerraformFolderToTemp(t, "../../", "examples/gcp/unit/vpc")
17 | region := gcp.GetRandomRegion(t, projectId, []string{"us-west1", "us-central1", "us-east1"}, nil)
18 | terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
19 | TerraformDir: exampleDir,
20 | Vars: map[string]interface{}{
21 | "gcp_project_region": region,
22 | "gcp_network_name": randomValidNetworkGcpName,
23 | "gcp_project_id": projectId,
24 | },
25 | EnvVars: map[string]string{
26 | "GOOGLE_PROJECT": projectId,
27 | "GOOGLE_CREDENTIALS": gsCreds,
28 | },
29 | })
30 | defer terraform.Destroy(t, terraformOptions)
31 | terraform.InitAndApply(t, terraformOptions)
32 | }
33 |
--------------------------------------------------------------------------------
/variables.tf:
--------------------------------------------------------------------------------
1 | variable "gcp_project_id" {
2 | type = string
3 | default = "test"
4 | description = "Your static IP network nameP. [Naming resources convention](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
5 | validation {
6 | condition = can(regex("^[a-z0-9][-a-z0-9]*[a-z0-9]$", var.gcp_project_id))
7 | error_message = "Error: Your Google Cloud Project ID seems to have an invalid value."
8 | }
9 | }
10 |
11 | variable "gcp_project_region" {
12 | type = string
13 | default = "us-west1"
14 | description = "Zone location of your instance, [see the list of available regions](https://cloud.google.com/compute/docs/regions-zones#available) - [Terraform provider documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#zone)"
15 | validation {
16 | condition = can(index(["us-west1", "us-central1", "us-east1"], var.gcp_project_region))
17 | error_message = "Error: Only some U.S. regions are available regarding the free offer of GCP Compute VM instances."
18 | }
19 | }
20 |
21 | variable "gcp_instance_name" {
22 | type = string
23 | default = "gcp-machine"
24 | description = "Your VM instance name. [Naming resources convention](https://cloud.google.com/compute/docs/naming-resources#resource-name-format)"
25 | validation {
26 | condition = can(regex("^[a-z0-9][-a-z0-9]*[a-z0-9]$", var.gcp_instance_name))
27 | error_message = "Error: The instance name can contain only dashes, lowercase letters, and numbers. It must be at least 2 characters and can neither start nor end with a dash."
28 | }
29 | }
30 |
31 | variable "gcp_storage_permissions" {
32 | type = string
33 | default = "publicread"
34 | description = "See all available values for the parameter at [Predefined ACL's on GCS Permissions](https://cloud.google.com/storage/docs/access-control/lists#predefined-acl)"
35 | validation {
36 | condition = can(index(["private", "bucketownerread", "bucketOwnerfullcontrol", "projectprivate", " authenticateread", "publicread", "publicreadwrite"], var.gcp_storage_permissions))
37 | error_message = "Error: Invalid permissions set for GCS Bucket. Please adjust it according to the documentation.."
38 | }
39 | }
40 |
41 | variable "aws_default_region" {
42 | type = string
43 | default = "us-east-1"
44 | description = "Your default region for AWS resources creation. [Available regions for Google Compute on Free Tier.](https://free.terraform.gruber.dev.br/docs/resources/providers/aws#options)"
45 | }
46 |
47 | variable "backend_destroy" {
48 | type = string
49 | default = "false"
50 | description = "Allows destroying all resourcesinside the configured S3 Remote Backend. See more at [tf-free's Backend Documentation](https://free.terraform.gruber.dev.br/docs/setup/backend)"
51 | validation {
52 | condition = can(index(["false", "true"], var.backend_destroy))
53 | error_message = "Error: Only 'true' or 'false' input as a string are acceptable values to this variable."
54 | }
55 | }
56 |
57 | variable "prevents_destroy" {
58 | type = bool
59 | default = true
60 | description = "Prevents destroying the previously provisioned S3 Remote Backend. See more at [tf-free's Backend Documentation](https://free.terraform.gruber.dev.br/docs/setup/backend)"
61 | }
62 |
63 | variable "backend_stage" {
64 | type = string
65 | default = "test"
66 | description = "Stages possible for Backend. Set for a random string."
67 | }
68 |
69 | variable "ec2_aws" {
70 | description = "Allow for the creation of EC2 instances on AWS."
71 | type = bool
72 | default = true
73 | }
74 |
75 | variable "rds_aws" {
76 | description = "Allow for the creation of a PostgreSQL database on AWS"
77 | type = bool
78 | default = true
79 | }
80 |
--------------------------------------------------------------------------------
/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.13"
3 | required_providers {
4 | google = {
5 | source = "hashicorp/google"
6 | version = "4.31.0"
7 | }
8 | google-beta = {
9 | source = "hashicorp/google-beta"
10 | version = "4.31.0"
11 | }
12 | aws = {
13 | source = "hashicorp/aws"
14 | version = "4.25.0"
15 | }
16 | azurerm = {
17 | source = "hashicorp/azurerm"
18 | version = "3.17.0"
19 | }
20 | }
21 | }
22 |
23 | provider "aws" {
24 | region = var.aws_default_region
25 | }
26 |
27 | provider "google" {
28 | region = var.gcp_project_region
29 | }
30 |
31 | provider "google-beta" {
32 | region = var.gcp_project_region
33 | }
34 |
35 | provider "azurerm" {
36 | features {}
37 | }
38 |
--------------------------------------------------------------------------------