Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add automatic log drains for addons #10

Merged
merged 2 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ Used in production by :
| [scalingo_container_type.containers](https://registry.terraform.io/providers/scalingo/scalingo/latest/docs/resources/container_type) | resource |
| [scalingo_domain.canonical_domain](https://registry.terraform.io/providers/scalingo/scalingo/latest/docs/resources/domain) | resource |
| [scalingo_domain.domain_aliases](https://registry.terraform.io/providers/scalingo/scalingo/latest/docs/resources/domain) | resource |
| [scalingo_log_drain.log_drain](https://registry.terraform.io/providers/scalingo/scalingo/latest/docs/resources/log_drain) | resource |
| [scalingo_log_drain.addons](https://registry.terraform.io/providers/scalingo/scalingo/latest/docs/resources/log_drain) | resource |
| [scalingo_log_drain.app](https://registry.terraform.io/providers/scalingo/scalingo/latest/docs/resources/log_drain) | resource |
| [scalingo_scm_repo_link.scm_repo_link](https://registry.terraform.io/providers/scalingo/scalingo/latest/docs/resources/scm_repo_link) | resource |

## Inputs
Expand All @@ -74,8 +75,8 @@ Used in production by :
| <a name="input_environment"></a> [environment](#input\_environment) | Map of environment variables to set on the application. Note that value of environment variables can be null or empty. | `map(string)` | `null` | no |
| <a name="input_github_integration"></a> [github\_integration](#input\_github\_integration) | Configuration of the GitHub integration of the application. Only one of github\_integration or gitlab\_integration can be set. | <pre>object({<br> repo_url = string<br> integration_uuid = optional(string)<br> branch = optional(string, "main")<br> auto_deploy_enabled = optional(bool, true)<br> })</pre> | `null` | no |
| <a name="input_gitlab_integration"></a> [gitlab\_integration](#input\_gitlab\_integration) | Configuration of the GitLab integration of the application. Only one of github\_integration or gitlab\_integration can be set. | <pre>object({<br> repo_url = string<br> integration_uuid = optional(string)<br> branch = optional(string, "main")<br> auto_deploy_enabled = optional(bool, true)<br> })</pre> | `null` | no |
| <a name="input_log_drains"></a> [log\_drains](#input\_log\_drains) | n/a | <pre>list(object({<br> type = string<br> url = optional(string, "")<br> drain_region = optional(string, "")<br> addon = optional(string, "")<br> host = optional(string, "")<br> port = optional(string, "")<br> token = optional(string, "")<br> }))</pre> | `[]` | no |
| <a name="input_name"></a> [name](#input\_name) | n/a | `string` | n/a | yes |
| <a name="input_log_drains"></a> [log\_drains](#input\_log\_drains) | List of log\_drain configuration to redirect logs from the application and addons to a log management service. Each configuration is automatically associated to the application and to every eligible addons. | <pre>list(object({<br> type = string<br> url = optional(string, "")<br> drain_region = optional(string, "")<br> host = optional(string, "")<br> port = optional(string, "")<br> token = optional(string, "")<br> }))</pre> | `[]` | no |
| <a name="input_name"></a> [name](#input\_name) | Name of the application. Must be unique on Scalingo. | `string` | n/a | yes |
| <a name="input_review_apps"></a> [review\_apps](#input\_review\_apps) | Configuration of the review apps of the application. | <pre>object({<br> enabled = optional(bool, false)<br><br> # By default: delete review apps 0 hours after closing the PR<br> delete_on_close_enabled = optional(bool, true)<br> hours_before_delete_on_close = optional(string, "0")<br><br> # By default: delete review apps after 5 days of inactivity (= no new deployment)<br> delete_stale_enabled = optional(bool, true)<br> hours_before_delete_stale = optional(string, "168")<br><br> # By default: do not create review apps for PRs from forks<br> automatic_creation_from_forks_allowed = optional(bool, false)<br> })</pre> | `{}` | no |
| <a name="input_router_logs"></a> [router\_logs](#input\_router\_logs) | When true, the router logs are included in the application logs. (default: `false`) | `bool` | `false` | no |
| <a name="input_stack"></a> [stack](#input\_stack) | The stack to use for the app (default: "scalingo-22"). | `string` | `"scalingo-22"` | no |
Expand Down
28 changes: 26 additions & 2 deletions log_drains.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Log drains
# How it works :https://doc.scalingo.com/platform/app/log-drain
# API Docs : https://developers.scalingo.com/log_drains
resource "scalingo_log_drain" "log_drain" {

# Log drains for applications
resource "scalingo_log_drain" "app" {
for_each = { for log_drain in var.log_drains : log_drain.type => log_drain }

app = scalingo_app.app.id
Expand All @@ -11,7 +13,29 @@ resource "scalingo_log_drain" "log_drain" {
# Log drain parameters are different depending on the type
url = sensitive(each.value.url)
drain_region = each.value.drain_region
addon = each.value.addon
host = each.value.host
port = each.value.port
token = sensitive(each.value.token)
}

# Log drains for addons
resource "scalingo_log_drain" "addons" {
# Create a map of log_drain for each addon and log_drain combination :
# e.g. { "redis-elk" = { addon_id = "xxxx", type = "elk", url = "https://elk.example.com/xxxx" } }
for_each = { for log_drain in setproduct(var.log_drains, values(scalingo_addon.addons)) :
"${log_drain[1].provider_id}-${log_drain[0].type}"
=> merge(log_drain[0], { addon_id = log_drain[1].id })
}

# Associate the log drain to app AND addon
app = scalingo_app.app.id
addon = each.value.addon_id

type = each.value.type

# Log drain parameters are different depending on the type
url = sensitive(each.value.url)
drain_region = each.value.drain_region
host = each.value.host
port = each.value.port
token = sensitive(each.value.token)
Expand Down
35 changes: 35 additions & 0 deletions upgrade_to_v0.3.0.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
### Migration from v0.2.0 of the module
### REMOVE when releasing v1.0.0

moved {
from = scalingo_log_drain.log_drain["elk"]
to = scalingo_log_drain.app["elk"]
}
moved {
from = scalingo_log_drain.log_drain["appsignal"]
to = scalingo_log_drain.app["appsignal"]
}
moved {
from = scalingo_log_drain.log_drain["logtail"]
to = scalingo_log_drain.app["logtail"]
}
moved {
from = scalingo_log_drain.log_drain["datadog"]
to = scalingo_log_drain.app["datadog"]
}
moved {
from = scalingo_log_drain.log_drain["ovh-graylog"]
to = scalingo_log_drain.app["ovh-graylog"]
}
moved {
from = scalingo_log_drain.log_drain["papertrail"]
to = scalingo_log_drain.app["papertrail"]
}
moved {
from = scalingo_log_drain.log_drain["logtail"]
to = scalingo_log_drain.app["logtail"]
}
moved {
from = scalingo_log_drain.log_drain["syslog"]
to = scalingo_log_drain.app["syslog"]
}
13 changes: 11 additions & 2 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
variable "name" {
type = string
description = "Name of the application. Must be unique on Scalingo."
type = string
}

variable "stack" {
Expand Down Expand Up @@ -183,11 +184,11 @@ variable "domain_aliases" {
}

variable "log_drains" {
description = "List of log_drain configuration to redirect logs from the application and addons to a log management service. Each configuration is automatically associated to the application and to every eligible addons."
type = list(object({
type = string
url = optional(string, "")
drain_region = optional(string, "")
addon = optional(string, "")
host = optional(string, "")
port = optional(string, "")
token = optional(string, "")
Expand All @@ -202,4 +203,12 @@ variable "log_drains" {
]) == 0
error_message = "The list of log drains must contain only valid log drains type (elk/appsignal/logtail/datadog/ovh-graylog/papertrail/logtail/syslog)."
}

validation {
condition = length([
for drain in var.log_drains :
drain if drain.type == "elk" && can(length(regex("^https?://([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", drain.url)) == 0)
]) == 0
error_message = "Log drains of type \"elk\" must have a valid url."
}
}