Skip to content

Commit db89cb2

Browse files
mariusz89016mariusz.wojakowski
andauthored
feat: Configure platform in Infracost comment command (#14)
Co-authored-by: mariusz.wojakowski <[email protected]>
1 parent e6e35dd commit db89cb2

File tree

3 files changed

+61
-15
lines changed

3 files changed

+61
-15
lines changed

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,24 @@ module "template" {
4949
}
5050
}
5151
```
52+
53+
### Infracost configuration
54+
55+
Every workflow can have separately configurable Infracost post workflow hook. As you can see in the example above
56+
to enable it you need to set `enabled` parameter to true.
57+
Other parameters are:
58+
* `platform` - used to configure which platform Infracost should interact with.
59+
Currently supported are: GitHub, GitLab and Bitbucket.
60+
* `token_environment_variable` - used to specifying a custom environment variable with an access token
61+
to use to authorize when posting comments
62+
* `behavior` - used to configuring how comments are posted. Possible values: update, hide-and-new, delete-and-new and new.
63+
For more details see: https://www.infracost.io/docs/features/cli_commands/
64+
65+
#### Autoconfiguration based on platform
66+
67+
If you don't specify `token_environment_variable` then an environment variable with an access token will be chosen
68+
automatically based on specified platform, e.g. on GitLab it will be `ATLANTIS_GITLAB_TOKEN`.
69+
5270
## EXAMPLES
5371

5472
- [Complete example](examples/complete)
@@ -65,7 +83,7 @@ module "template" {
6583
| <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 |
6684
| <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 |
6785
| <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 |
86+
| <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> platform = optional(string, "gitlab")<br> token_environment_variable = optional(string)<br> behavior = optional(string, "new")<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 |
6987

7088
## Modules
7189

main.tf

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ locals {
22
#Repo attributes that are meant to simplify configuration rather than being actual repo options
33
helper_options = ["allow_all_server_side_workflows", "terragrunt_atlantis_config", "infracost"]
44

5+
infracost_parameters = {
6+
github : { token_name : "gh-token", environment_variable_name : "ATLANTIS_GH_TOKEN" },
7+
gitlab : { token_name : "gitlab-token", environment_variable_name : "ATLANTIS_GITLAB_TOKEN" },
8+
bitbucket : { token_name : "bitbucket-token", environment_variable_name : "ATLANTIS_BITBUCKET_TOKEN" }
9+
}
10+
511
#Remove all options that are null
612
repos_with_non_null_values = [
713
for repo in var.repos : merge(
@@ -50,19 +56,28 @@ locals {
5056
lookup(repo, "post_workflow_hooks", []),
5157
lookup(repo, "workflow", "") != "" && lookup(local._workflows, lookup(repo, "workflow", ""), "") != "" ? (
5258
local._workflows[lookup(repo, "workflow", "")].infracost.enabled ? [
53-
{ run : <<EOT
54-
if [ ! -d "/tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM" ]; then
55-
exit 0
56-
fi
57-
58-
infracost comment gitlab --repo $BASE_REPO_OWNER/$BASE_REPO_NAME \
59-
--merge-request $PULL_NUM \
60-
--path /tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM/'*'-infracost.json \
61-
--gitlab-token $GITLAB_TOKEN \
62-
--behavior new
63-
64-
rm -rf /tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM
65-
EOT
59+
{ run : join("", [
60+
"if [ ! -d \"/tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM\" ]; then exit 0; fi",
61+
"\n\n",
62+
join(" ", [
63+
"infracost",
64+
"comment",
65+
local._workflows[lookup(repo, "workflow", "")].infracost.platform,
66+
"--repo $BASE_REPO_OWNER/$BASE_REPO_NAME",
67+
"--merge-request $PULL_NUM",
68+
"--path /tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM/'*'-infracost.json",
69+
format("--%s $%s",
70+
local.infracost_parameters[local._workflows[repo.workflow].infracost.platform].token_name,
71+
coalesce(
72+
local._workflows[repo.workflow].infracost.token_environment_variable,
73+
local.infracost_parameters[local._workflows[repo.workflow].infracost.platform].environment_variable_name)
74+
),
75+
format("--behavior %s", local._workflows[lookup(repo, "workflow", "")].infracost.behavior)
76+
]),
77+
"\n\n",
78+
"rm -rf /tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM"
79+
]
80+
)
6681
}
6782
] : []) : []
6883
)

variables.tf

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,10 @@ variable "workflows" {
136136
file = optional(string, "$SHOWFILE")
137137
}), {})
138138
infracost = optional(object({
139-
enabled = optional(bool, false)
139+
enabled = optional(bool, false)
140+
platform = optional(string, "gitlab")
141+
token_environment_variable = optional(string)
142+
behavior = optional(string, "new")
140143
}), {})
141144
pull_gitlab_variables = optional(object({
142145
enabled = optional(bool, false)
@@ -180,6 +183,16 @@ variable "workflows" {
180183
]))
181184
error_message = "Invalid command in `atlantis_step`. Allowed values: init, plan, show, policy_check, apply, version, import, state_rm"
182185
}
186+
187+
validation {
188+
condition = alltrue([for workflow_name, workflow in var.workflows : contains(["github", "gitlab", "bitbucket"], workflow.infracost.platform)])
189+
error_message = "Invalid platform in `infracost`. Allowed values: github, gitlab, bitbucket"
190+
}
191+
192+
validation {
193+
condition = alltrue([for workflow_name, workflow in var.workflows : contains(["update", "hide-and-new", "delete-and-new", "new"], workflow.infracost.behavior)])
194+
error_message = "Invalid behavior in `infracost`. Allowed values: update, hide-and-new, delete-and-new, new"
195+
}
183196
}
184197

185198
variable "repo_config_file" {

0 commit comments

Comments
 (0)