Skip to content

Commit

Permalink
[tf-module:push-notifications] Dedup logic and SNS platform app resou…
Browse files Browse the repository at this point in the history
…rces

This changeset unifies both platform resources. This is possible because
TF - for once - behaves as expected and drops a resource attribute that
is set to 'null'.
This also helps to deduplicate the logic that is used to massage the app
lists inputs to cope with 'for_each'.

Allow the list of apps to not being set. Because this is now allowed, the
overall existence of any application is used as indicator to figure out
whether the IAM policy has to be created or not.
  • Loading branch information
lucendio committed Oct 7, 2020
1 parent 507543a commit 939f568
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ resource "aws_iam_access_key" "gundeck" {
# and to consume messages from the SQS queues
#
resource "aws_iam_user_policy" "gundeck" {
count = length(aws_sns_platform_application.apps) > 0 ? 1 : 0

name = "${var.environment}-gundeck-full-access-policy"
user = aws_iam_user.gundeck.name

Expand Down Expand Up @@ -39,10 +41,9 @@ resource "aws_iam_user_policy" "gundeck" {
"sns:SetEndpointAttributes",
"sns:Publish"
],
"Resource": ${jsonencode(concat(
[for _, v in aws_sns_platform_application.android : v.arn],
[for _, v in aws_sns_platform_application.ios : v.arn]
))}
"Resource": ${jsonencode(
[for _, v in aws_sns_platform_application.apps : v.arn]
)}
}
]
}
Expand Down
77 changes: 38 additions & 39 deletions terraform/modules/aws-gundeck-push-notifications/resources.sns.tf
Original file line number Diff line number Diff line change
@@ -1,55 +1,54 @@
# Create platform applications for iOS and Android. At the moment, only VoIP is being used for iOS
# Create platform applications for iOS and Android.

resource "aws_sns_platform_application" "ios" {
for_each = {
for _, app_platform in flatten([
for _, app in var.ios_applications : [
for _, platform in app.platforms : merge({ platform = platform }, app)
]
]) : "${app_platform.id}-${app_platform.platform}" => app_platform
}
locals {

name = "${var.environment}-${each.value.id}"
# ^-- <env>-<bundleID>
# <env> should match the env on gundeck's config
# <bundleID> name of the application, which is bundled/hardcoded when the app is built
# NOTE: Well, well, well, we got ourselves yet another 'bug' - or more precisely - an unexpected
# behaviour. One would think, that
#
# The name of the app is IMPORTANT! If it does not follow the pattern, then apps will not be able
# to register for push notifications
# More details: https://github.com/zinfra/backend-wiki/wiki/Native-Push-Notifications#ios
# concat(var.ios_applications, var.android_applications)
#
platform = each.value.platform
# ^-- We only use VoIP at the moment
platform_principal = each.value.cert
# ^-- Path to the public certificate
platform_credential = each.value.key
# ^-- Path to the private key
event_delivery_failure_topic_arn = aws_sns_topic.device_state_changed.arn
# ^-- Topic to subscribe to
event_endpoint_updated_topic_arn = aws_sns_topic.device_state_changed.arn
# ^-- Topic to subscribe to
}
# would be the plausible choice for this task, but no, here comes Terraform.
# 'Hold my beer', it says: https://github.com/hashicorp/terraform/issues/26090
# tl;dr It eats all the fields that are NOT part of the items's intersection
# because different types. Admittedly, a reasonable explanation, but unexpected
# nonetheless. In order to work around it, we are pulling out the iron.
applications = flatten([var.ios_applications, var.android_applications])

resource "aws_sns_platform_application" "android" {
for_each = {
# NOTE: creates a map with the following identifier syntax: '${id}-${platform}'
app_platforms = {
for _, app_platform in flatten([
for _, app in var.android_applications : [
for _, app in local.applications : [
for _, platform in app.platforms : merge({ platform = platform }, app)
]
]) : "${app_platform.id}-${app_platform.platform}" => app_platform
}

name = "${var.environment}-${each.value.id}"
# ^-- <env>-<projectID>
#
# <env> should match the env on gundeck's config
# <projectID> name of the firebase project (this is unique across all firebase projects)
#
# More details: https://github.com/zinfra/backend-wiki/wiki/Native-Push-Notifications#android
}

resource "aws_sns_platform_application" "apps" {
for_each = local.app_platforms

# The name of the app is IMPORTANT! If it does not follow the pattern, then apps will not be able
# to register for push notifications
# [iOS] More details: https://github.com/zinfra/backend-wiki/wiki/Native-Push-Notifications#ios
# [Android] More details: https://github.com/zinfra/backend-wiki/wiki/Native-Push-Notifications#android
#
platform = each.value.platform
name = "${var.environment}-${each.value.id}"
# ^-- [iOS] <env>-<bundleID>
# ^-- [Android] <env>-<projectID>
# <env> should match the env on gundeck's config
# <bundleID> name of the application, which is bundled/hardcoded when the app is built
# <projectID> name of the firebase project (this is unique across all firebase projects)

# NOTE: possible values https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html#sns-attrib-mobile-reserved
platform = each.value.platform

platform_credential = each.value.key
# ^-- Path to the secret token
# ^-- [iOS] Content of to the private key
# ^-- [Android] Content of the secret token
platform_principal = lookup(each.value, "cert", null)
# ^-- [iOS] Content of the public certificate

event_delivery_failure_topic_arn = aws_sns_topic.device_state_changed.arn
# ^-- Topic to subscribe to
event_endpoint_updated_topic_arn = aws_sns_topic.device_state_changed.arn
Expand Down
2 changes: 2 additions & 0 deletions terraform/modules/aws-gundeck-push-notifications/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ variable "ios_applications" {
cert = string # docs: https://www.terraform.io/docs/providers/aws/r/sns_platform_application.html#platform_principal
}))
description = "list of iOS applications and their credentials to be registered for push notifications (SNS)"
default = []
}


Expand All @@ -31,6 +32,7 @@ variable "android_applications" {
key = string # docs: https://www.terraform.io/docs/providers/aws/r/sns_platform_application.html#platform_credential
}))
description = "list of iOS applications and their credentials to be registered for push notifications (SNS)"
default = []
}


Expand Down

0 comments on commit 939f568

Please sign in to comment.