Skip to content

Commit 4a83370

Browse files
Merge pull request #11 from getindata/infracost
feat: New configuration with infracost
2 parents 03db1ac + 365310e commit 4a83370

File tree

4 files changed

+80
-36
lines changed

4 files changed

+80
-36
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ module "template" {
4242
}
4343
4444
checkov = { enabled = true, soft_fail = true }
45+
infracost = { enabled = true }
4546
check_gitlab_approvals = { enabled = true }
4647
asdf = { enabled = true }
4748
}
@@ -62,9 +63,9 @@ module "template" {
6263
| Name | Description | Type | Default | Required |
6364
|------|-------------|------|---------|:--------:|
6465
| <a name="input_repo_config_file"></a> [repo\_config\_file](#input\_repo\_config\_file) | Configures config file generation if enabled | <pre>object({<br> enabled = optional(bool, false)<br> path = optional(string, ".")<br> name = optional(string, "repo_config.yaml")<br> format = optional(string, "yaml")<br> })</pre> | `{}` | no |
65-
| <a name="input_repos"></a> [repos](#input\_repos) | Map of repositories and their configs. Refer to https://www.runatlantis.io/docs/server-side-repo-config.html#example-server-side-repo | <pre>list(object({<br> id = optional(string, "/.*/")<br> branch = optional(string)<br> apply_requirements = optional(list(string))<br> allowed_overrides = optional(list(string))<br> allowed_workflows = optional(list(string))<br> allow_custom_workflows = optional(bool)<br> delete_source_branch_on_merge = optional(bool)<br> pre_workflow_hooks = optional(list(object({<br> run = string<br> })))<br> post_workflow_hooks = optional(list(object({<br> run = string<br> })))<br> workflow = optional(string)<br> ######### Helpers #########<br> allow_all_server_side_workflows = optional(bool, false)<br> terragrunt_atlantis_config = optional(object({<br> enabled = optional(bool, false)<br> output = optional(string, "atlantis.yaml")<br> automerge = optional(bool)<br> autoplan = optional(bool)<br> parallel = optional(bool)<br> cascade_dependencies = optional(bool)<br> filter = optional(string)<br> use_project_markers = optional(bool)<br> }), {})<br> }))</pre> | `[]` | no |
66-
| <a name="input_repos_common_config"></a> [repos\_common\_config](#input\_repos\_common\_config) | Common config that will be merged into each item of the repos list | <pre>object({<br> id = optional(string)<br> branch = optional(string)<br> apply_requirements = optional(list(string))<br> allowed_overrides = optional(list(string))<br> allowed_workflows = optional(list(string))<br> allow_custom_workflows = optional(bool)<br> delete_source_branch_on_merge = optional(bool)<br> pre_workflow_hooks = optional(list(object({<br> run = string<br> })))<br> post_workflow_hooks = optional(list(object({<br> run = string<br> })))<br> workflow = optional(string)<br> ######### Helpers #########<br> allow_all_server_side_workflows = optional(bool, false)<br> terragrunt_atlantis_config = optional(object({<br> enabled = optional(bool, false)<br> output = optional(string, "atlantis.yaml")<br> autoplan = optional(bool, false)<br> parallel = optional(bool, false)<br> filter = optional(string)<br> }), {})<br> })</pre> | `{}` | no |
67-
| <a name="input_workflows"></a> [workflows](#input\_workflows) | List of custom workflow that will be added to the repo config file | <pre>map(object({<br> plan = optional(object({<br> steps = optional(list(object({<br> env = optional(object({<br> name = string<br> command = string<br> }))<br> run = optional(string)<br> multienv = optional(string)<br> atlantis_step = optional(object({<br> command = string<br> extra_args = optional(list(string))<br> }))<br> })))<br> }))<br> apply = optional(object({<br> steps = optional(list(object({<br> env = optional(object({<br> name = string<br> command = string<br> }))<br> run = optional(string)<br> multienv = optional(string)<br> atlantis_step = optional(object({<br> command = string<br> extra_args = optional(list(string))<br> }))<br> })))<br> }))<br> import = optional(object({<br> steps = optional(list(object({<br> env = optional(object({<br> name = string<br> command = string<br> }))<br> run = optional(string)<br> multienv = optional(string)<br> atlantis_step = optional(object({<br> command = string<br> extra_args = optional(list(string))<br> }))<br> })))<br> }))<br> state_rm = optional(object({<br> steps = optional(list(object({<br> env = optional(object({<br> name = string<br> command = string<br> }))<br> run = optional(string)<br> multienv = optional(string)<br> atlantis_step = optional(object({<br> command = string<br> extra_args = optional(list(string))<br> }))<br> })))<br> }))<br> template = optional(string, "terragrunt-basic")<br> asdf = optional(object({<br> enabled = optional(bool, false)<br> }), {})<br> checkov = optional(object({<br> enabled = optional(bool, false)<br> soft_fail = optional(bool, false)<br> file = optional(string, "$SHOWFILE")<br> }), {})<br> pull_gitlab_variables = optional(object({<br> enabled = optional(bool, false)<br> }), {})<br> check_gitlab_approvals = optional(object({<br> enabled = optional(bool, false)<br> }), {}),<br> }))</pre> | `{}` | no |
66+
| <a name="input_repos"></a> [repos](#input\_repos) | Map of repositories and their configs. Refer to https://www.runatlantis.io/docs/server-side-repo-config.html#example-server-side-repo | <pre>list(object({<br> id = optional(string, "/.*/")<br> branch = optional(string)<br> apply_requirements = optional(list(string))<br> allowed_overrides = optional(list(string))<br> allowed_workflows = optional(list(string), [])<br> allow_custom_workflows = optional(bool)<br> delete_source_branch_on_merge = optional(bool)<br> pre_workflow_hooks = optional(list(object({<br> run = string<br> })))<br> post_workflow_hooks = optional(list(object({<br> run = string<br> })))<br> workflow = optional(string)<br> ######### Helpers #########<br> allow_all_server_side_workflows = optional(bool, false)<br> terragrunt_atlantis_config = optional(object({<br> enabled = optional(bool)<br> output = optional(string)<br> automerge = optional(bool)<br> autoplan = optional(bool)<br> parallel = optional(bool)<br> cascade_dependencies = optional(bool)<br> filter = optional(string)<br> use_project_markers = optional(bool)<br> }), {})<br> }))</pre> | `[]` | no |
67+
| <a name="input_repos_common_config"></a> [repos\_common\_config](#input\_repos\_common\_config) | Common config that will be merged into each item of the repos list | <pre>object({<br> id = optional(string)<br> branch = optional(string)<br> apply_requirements = optional(list(string))<br> allowed_overrides = optional(list(string))<br> allowed_workflows = optional(list(string))<br> allow_custom_workflows = optional(bool)<br> delete_source_branch_on_merge = optional(bool)<br> pre_workflow_hooks = optional(list(object({<br> run = string<br> })))<br> post_workflow_hooks = optional(list(object({<br> run = string<br> })))<br> workflow = optional(string)<br> ######### Helpers #########<br> allow_all_server_side_workflows = optional(bool, false)<br> terragrunt_atlantis_config = optional(object({<br> enabled = optional(bool, false)<br> output = optional(string, "atlantis.yaml")<br> automerge = optional(bool)<br> autoplan = optional(bool)<br> parallel = optional(bool)<br> cascade_dependencies = optional(bool)<br> filter = optional(string)<br> use_project_markers = optional(bool)<br> }), {})<br> infracost = optional(object({<br> enabled = optional(bool, false)<br> }), {})<br> })</pre> | `{}` | no |
68+
| <a name="input_workflows"></a> [workflows](#input\_workflows) | List of custom workflow that will be added to the repo config file | <pre>map(object({<br> plan = optional(object({<br> steps = optional(list(object({<br> env = optional(object({<br> name = string<br> command = string<br> }))<br> run = optional(string)<br> multienv = optional(string)<br> atlantis_step = optional(object({<br> command = string<br> extra_args = optional(list(string))<br> }))<br> })))<br> }))<br> apply = optional(object({<br> steps = optional(list(object({<br> env = optional(object({<br> name = string<br> command = string<br> }))<br> run = optional(string)<br> multienv = optional(string)<br> atlantis_step = optional(object({<br> command = string<br> extra_args = optional(list(string))<br> }))<br> })))<br> }))<br> import = optional(object({<br> steps = optional(list(object({<br> env = optional(object({<br> name = string<br> command = string<br> }))<br> run = optional(string)<br> multienv = optional(string)<br> atlantis_step = optional(object({<br> command = string<br> extra_args = optional(list(string))<br> }))<br> })))<br> }))<br> state_rm = optional(object({<br> steps = optional(list(object({<br> env = optional(object({<br> name = string<br> command = string<br> }))<br> run = optional(string)<br> multienv = optional(string)<br> atlantis_step = optional(object({<br> command = string<br> extra_args = optional(list(string))<br> }))<br> })))<br> }))<br> template = optional(string, "terragrunt-basic")<br> asdf = optional(object({<br> enabled = optional(bool, false)<br> }), {})<br> checkov = optional(object({<br> enabled = optional(bool, false)<br> soft_fail = optional(bool, false)<br> file = optional(string, "$SHOWFILE")<br> }), {})<br> infracost = optional(object({<br> enabled = optional(bool, false)<br> }), {})<br> pull_gitlab_variables = optional(object({<br> enabled = optional(bool, false)<br> }), {})<br> check_gitlab_approvals = optional(object({<br> enabled = optional(bool, false)<br> }), {}),<br> }))</pre> | `{}` | no |
6869

6970
## Modules
7071

examples/complete/main.tf

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,20 @@ module "repo_config" {
1919

2020
terragrunt_atlantis_config = {
2121
enabled = true
22-
autoplan = true
22+
parallel = false
23+
autoplan = false
2324
}
2425
}
2526
]
2627

2728
repos_common_config = {
2829
apply_requirements = ["approved", "mergeable"]
2930
branch = "/main/"
31+
32+
terragrunt_atlantis_config = {
33+
enabled = true
34+
autoplan = true
35+
}
3036
}
3137

3238
workflows = {

main.tf

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ locals {
66
repos_with_non_null_values = [
77
for repo in var.repos : merge(
88
{ for k, v in var.repos_common_config : k => v if v != null },
9-
{ for k, v in repo : k => v if v != null }
9+
{ for k, v in repo : k => v if v != null },
10+
{ terragrunt_atlantis_config : merge(
11+
var.repos_common_config.terragrunt_atlantis_config,
12+
{ for k, v in repo.terragrunt_atlantis_config : k => v if v != null }
13+
) }
1014
)
1115
]
1216
#Apply helper variables and then remove them
@@ -15,28 +19,47 @@ locals {
1519
{
1620
for k, v in repo : k => v if contains(local.helper_options, k) == false
1721
},
18-
repo.allow_all_server_side_workflows ? { allowed_workflows = keys(local.workflows) } : {},
19-
repo.terragrunt_atlantis_config.enabled ? { pre_workflow_hooks = concat(lookup(repo, "pre_workflow_hooks", []), [
20-
{
21-
run : join(" ", compact(
22-
[
23-
"terragrunt-atlantis-config",
24-
"generate",
25-
format("--output \"%s\"", repo.terragrunt_atlantis_config.output),
26-
repo.terragrunt_atlantis_config.filter != null ? format("--filter \"%s\"", repo.terragrunt_atlantis_config.filter) : null,
27-
repo.terragrunt_atlantis_config.parallel != null ? format("--parallel=%s", repo.terragrunt_atlantis_config.parallel) : null,
28-
repo.terragrunt_atlantis_config.autoplan != null ? format("--autoplan=%s", repo.terragrunt_atlantis_config.autoplan) : null,
29-
repo.terragrunt_atlantis_config.automerge != null ? format("--automerge=%s", repo.terragrunt_atlantis_config.automerge) : null,
30-
repo.terragrunt_atlantis_config.cascade_dependencies != null ? format("--cascade-dependencies=%s", repo.terragrunt_atlantis_config.cascade_dependencies) : null,
31-
repo.terragrunt_atlantis_config.use_project_markers != null ? format("--use-project-markers=%s", repo.terragrunt_atlantis_config.use_project_markers) : null,
32-
]
33-
))
34-
}]) } : {},
35-
)]
22+
repo.allow_all_server_side_workflows ? { allowed_workflows = concat(repo.allowed_workflows, keys(local.workflows)) } : { allowed_workflows = repo.allowed_workflows },
23+
{
24+
pre_workflow_hooks = concat(
25+
lookup(repo, "pre_workflow_hooks", []),
26+
repo.terragrunt_atlantis_config.enabled ? [
27+
{
28+
run : join(" ", compact(
29+
[
30+
"terragrunt-atlantis-config",
31+
"generate",
32+
format("--output \"%s\"", repo.terragrunt_atlantis_config.output),
33+
repo.terragrunt_atlantis_config.filter != null ? format("--filter \"%s\"", repo.terragrunt_atlantis_config.filter) : null,
34+
repo.terragrunt_atlantis_config.parallel != null ? format("--parallel=%s", repo.terragrunt_atlantis_config.parallel) : null,
35+
repo.terragrunt_atlantis_config.autoplan != null ? format("--autoplan=%s", repo.terragrunt_atlantis_config.autoplan) : null,
36+
repo.terragrunt_atlantis_config.automerge != null ? format("--automerge=%s", repo.terragrunt_atlantis_config.automerge) : null,
37+
repo.terragrunt_atlantis_config.cascade_dependencies != null ? format("--cascade-dependencies=%s", repo.terragrunt_atlantis_config.cascade_dependencies) : null,
38+
repo.terragrunt_atlantis_config.use_project_markers != null ? format("--use-project-markers=%s", repo.terragrunt_atlantis_config.use_project_markers) : null,
39+
]
40+
))
41+
}
42+
] : [],
43+
lookup(repo, "workflow", "") != "" && lookup(local._workflows, lookup(repo, "workflow", ""), "") != "" ? (
44+
local._workflows[lookup(repo, "workflow", "")].infracost.enabled ? [
45+
{ run : "rm -rf /tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM" },
46+
{ run : "mkdir -p /tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM" }
47+
] : []) : []
48+
),
49+
post_workflow_hooks = concat(
50+
lookup(repo, "post_workflow_hooks", []),
51+
lookup(repo, "workflow", "") != "" && lookup(local._workflows, lookup(repo, "workflow", ""), "") != "" ? (
52+
local._workflows[lookup(repo, "workflow", "")].infracost.enabled ? [
53+
{ run : "infracost comment gitlab --repo $BASE_REPO_OWNER/$BASE_REPO_NAME --merge-request $PULL_NUM --path /tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM/'*'-infracost.json --gitlab-token $GITLAB_TOKEN --behavior new" }
54+
] : []) : []
55+
)
56+
})
57+
]
3658

37-
workflows_helper_options = ["asdf", "checkov", "pull_gitlab_variables", "check_gitlab_approvals", "template"]
59+
workflows_helper_options = ["asdf", "checkov", "pull_gitlab_variables", "check_gitlab_approvals", "template", "infracost"]
3860

39-
pre_workflows = {
61+
# tflint-ignore: terraform_naming_convention
62+
_workflows = {
4063
for workflow_name, workflow in var.workflows : workflow_name => {
4164
plan = merge(
4265
local.null_workflow.plan,
@@ -58,6 +81,7 @@ locals {
5881
asdf = workflow.asdf
5982
checkov = workflow.checkov
6083
check_gitlab_approvals = workflow.check_gitlab_approvals
84+
infracost = workflow.infracost
6185
}
6286
}
6387

@@ -66,7 +90,7 @@ locals {
6690
check_gitlab_approvals_steps = [{ run = "check-gitlab-approvals.sh" }]
6791

6892
workflows = {
69-
for workflow_name, workflow in local.pre_workflows : workflow_name => {
93+
for workflow_name, workflow in local._workflows : workflow_name => {
7094
for stage_name, stage in workflow : stage_name => { steps : concat(
7195
workflow.asdf.enabled && stage_name == "plan" ? local.asdf_steps : [],
7296
workflow.pull_gitlab_variables.enabled ? local.pull_gitlab_variables_steps : [],
@@ -93,7 +117,11 @@ locals {
93117
]
94118
))
95119
}
96-
] : []
120+
] : [],
121+
jsondecode(workflow.infracost.enabled && stage_name == "plan" ? jsonencode([
122+
{ env = { name = "INFRACOST_OUTPUT", command = "echo /tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM/$WORKSPACE-`echo $REPO_REL_DIR | sed 's#/#-#g'`-infracost.json" } },
123+
{ run = "infracost breakdown --path=$SHOWFILE --format=json --log-level=info --out-file=$INFRACOST_OUTPUT --project-name=$REPO_REL_DIR" }
124+
]) : jsonencode([]))
97125
) } if !contains(local.workflows_helper_options, stage_name) && lookup(stage, "steps", null) != null
98126
}
99127
}

0 commit comments

Comments
 (0)