The aws:sns/platformApplication:PlatformApplication resource, part of the Pulumi AWS provider, registers mobile push notification platforms with SNS for sending notifications to iOS and Android devices. This guide focuses on three capabilities: iOS certificate-based authentication, iOS token-based authentication, and Android GCM registration.
Platform applications require credentials from external providers: APNS certificates or signing keys from Apple Developer, or GCM API keys from Google Cloud Console. The examples are intentionally small. Combine them with your own device endpoint registration and notification publishing logic.
Register iOS apps with certificate-based authentication
iOS applications traditionally use certificate-based push notifications, requiring an APNS certificate and private key from Apple Developer.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const apnsApplication = new aws.sns.PlatformApplication("apns_application", {
name: "apns_application",
platform: "APNS",
platformCredential: "<APNS PRIVATE KEY>",
platformPrincipal: "<APNS CERTIFICATE>",
});
import pulumi
import pulumi_aws as aws
apns_application = aws.sns.PlatformApplication("apns_application",
name="apns_application",
platform="APNS",
platform_credential="<APNS PRIVATE KEY>",
platform_principal="<APNS CERTIFICATE>")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sns"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sns.NewPlatformApplication(ctx, "apns_application", &sns.PlatformApplicationArgs{
Name: pulumi.String("apns_application"),
Platform: pulumi.String("APNS"),
PlatformCredential: pulumi.String("<APNS PRIVATE KEY>"),
PlatformPrincipal: pulumi.String("<APNS CERTIFICATE>"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var apnsApplication = new Aws.Sns.PlatformApplication("apns_application", new()
{
Name = "apns_application",
Platform = "APNS",
PlatformCredential = "<APNS PRIVATE KEY>",
PlatformPrincipal = "<APNS CERTIFICATE>",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.sns.PlatformApplication;
import com.pulumi.aws.sns.PlatformApplicationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var apnsApplication = new PlatformApplication("apnsApplication", PlatformApplicationArgs.builder()
.name("apns_application")
.platform("APNS")
.platformCredential("<APNS PRIVATE KEY>")
.platformPrincipal("<APNS CERTIFICATE>")
.build());
}
}
resources:
apnsApplication:
type: aws:sns:PlatformApplication
name: apns_application
properties:
name: apns_application
platform: APNS
platformCredential: <APNS PRIVATE KEY>
platformPrincipal: <APNS CERTIFICATE>
The platform property specifies “APNS” for iOS. The platformCredential holds your APNS private key, while platformPrincipal contains the APNS certificate. SNS stores these as hashes in state, so they can’t be referenced by other resources. Once registered, you create platform endpoints for individual devices and publish notifications through SNS.
Register iOS apps with token-based authentication
Token-based authentication simplifies credential management by using a signing key instead of certificates, allowing one key to work across multiple apps.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const apnsApplication = new aws.sns.PlatformApplication("apns_application", {
name: "apns_application",
platform: "APNS",
platformCredential: "<APNS SIGNING KEY>",
platformPrincipal: "<APNS SIGNING KEY ID>",
applePlatformTeamId: "<APPLE TEAM ID>",
applePlatformBundleId: "<APPLE BUNDLE ID>",
});
import pulumi
import pulumi_aws as aws
apns_application = aws.sns.PlatformApplication("apns_application",
name="apns_application",
platform="APNS",
platform_credential="<APNS SIGNING KEY>",
platform_principal="<APNS SIGNING KEY ID>",
apple_platform_team_id="<APPLE TEAM ID>",
apple_platform_bundle_id="<APPLE BUNDLE ID>")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sns"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sns.NewPlatformApplication(ctx, "apns_application", &sns.PlatformApplicationArgs{
Name: pulumi.String("apns_application"),
Platform: pulumi.String("APNS"),
PlatformCredential: pulumi.String("<APNS SIGNING KEY>"),
PlatformPrincipal: pulumi.String("<APNS SIGNING KEY ID>"),
ApplePlatformTeamId: pulumi.String("<APPLE TEAM ID>"),
ApplePlatformBundleId: pulumi.String("<APPLE BUNDLE ID>"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var apnsApplication = new Aws.Sns.PlatformApplication("apns_application", new()
{
Name = "apns_application",
Platform = "APNS",
PlatformCredential = "<APNS SIGNING KEY>",
PlatformPrincipal = "<APNS SIGNING KEY ID>",
ApplePlatformTeamId = "<APPLE TEAM ID>",
ApplePlatformBundleId = "<APPLE BUNDLE ID>",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.sns.PlatformApplication;
import com.pulumi.aws.sns.PlatformApplicationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var apnsApplication = new PlatformApplication("apnsApplication", PlatformApplicationArgs.builder()
.name("apns_application")
.platform("APNS")
.platformCredential("<APNS SIGNING KEY>")
.platformPrincipal("<APNS SIGNING KEY ID>")
.applePlatformTeamId("<APPLE TEAM ID>")
.applePlatformBundleId("<APPLE BUNDLE ID>")
.build());
}
}
resources:
apnsApplication:
type: aws:sns:PlatformApplication
name: apns_application
properties:
name: apns_application
platform: APNS
platformCredential: <APNS SIGNING KEY>
platformPrincipal: <APNS SIGNING KEY ID>
applePlatformTeamId: <APPLE TEAM ID>
applePlatformBundleId: <APPLE BUNDLE ID>
Token-based authentication requires the signing key as platformCredential and the signing key ID as platformPrincipal. The applePlatformTeamId and applePlatformBundleId properties identify your Apple Developer account and app. This approach eliminates certificate expiration concerns and supports multiple apps with a single key.
Register Android apps with GCM credentials
Android applications use Google Cloud Messaging to deliver push notifications, requiring only an API key from Google Cloud Console.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const gcmApplication = new aws.sns.PlatformApplication("gcm_application", {
name: "gcm_application",
platform: "GCM",
platformCredential: "<GCM API KEY>",
});
import pulumi
import pulumi_aws as aws
gcm_application = aws.sns.PlatformApplication("gcm_application",
name="gcm_application",
platform="GCM",
platform_credential="<GCM API KEY>")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sns"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sns.NewPlatformApplication(ctx, "gcm_application", &sns.PlatformApplicationArgs{
Name: pulumi.String("gcm_application"),
Platform: pulumi.String("GCM"),
PlatformCredential: pulumi.String("<GCM API KEY>"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var gcmApplication = new Aws.Sns.PlatformApplication("gcm_application", new()
{
Name = "gcm_application",
Platform = "GCM",
PlatformCredential = "<GCM API KEY>",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.sns.PlatformApplication;
import com.pulumi.aws.sns.PlatformApplicationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var gcmApplication = new PlatformApplication("gcmApplication", PlatformApplicationArgs.builder()
.name("gcm_application")
.platform("GCM")
.platformCredential("<GCM API KEY>")
.build());
}
}
resources:
gcmApplication:
type: aws:sns:PlatformApplication
name: gcm_application
properties:
name: gcm_application
platform: GCM
platformCredential: <GCM API KEY>
The platform property specifies “GCM” for Android. The platformCredential contains your GCM API key. Unlike APNS, GCM doesn’t require a platformPrincipal property. After registration, you create endpoints for Android devices and publish notifications through the same SNS APIs used for iOS.
Beyond these examples
These snippets focus on specific platform application features: iOS certificate and token authentication, and Android GCM registration. They’re intentionally minimal rather than full push notification systems.
The examples require pre-existing infrastructure such as APNS certificates or signing keys from Apple Developer, and GCM API keys from Google Cloud Console. They focus on platform registration rather than device endpoint management or notification publishing.
To keep things focused, common platform application patterns are omitted, including:
- Event notification topics (endpoint lifecycle events)
- CloudWatch logging with IAM roles (success/failure feedback)
- Success feedback sampling (successFeedbackSampleRate)
These omissions are intentional: the goal is to illustrate how each platform authentication method is wired, not provide drop-in notification systems. See the SNS Platform Application resource reference for all available configuration options.
Let's create AWS SNS Platform Applications
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Platform Configuration & Authentication
platformCredential (private key) and platformPrincipal (certificate). Token-based authentication uses platformCredential (signing key), platformPrincipal (signing key ID), plus applePlatformTeamId and applePlatformBundleId.platformCredential set to your GCM API key. The platformPrincipal property is not needed for GCM.platformCredential and platformPrincipal values are stored as hashes in state, making them impractical to reference elsewhere. Store credentials in a secure parameter store or secrets manager and reference them directly where needed.APNS-Specific Configuration
applePlatformBundleId may only include alphanumeric characters, hyphens (-), and periods (.). This is your iOS app’s bundle identifier.applePlatformTeamId must be exactly 10 alphanumeric characters, matching your Apple developer account team identifier.Event Notifications & Monitoring
eventEndpointCreatedTopicArn for new endpoints, eventEndpointUpdatedTopicArn for changes, eventEndpointDeletedTopicArn for deletions, and eventDeliveryFailureTopicArn for permanent delivery failures.successFeedbackRoleArn and failureFeedbackRoleArn to IAM role ARNs that give SNS write access to CloudWatch logs. Optionally set successFeedbackSampleRate (0-100) to control the percentage of successful deliveries logged.Resource Management
name and platform properties are immutable and require resource replacement if changed.Using a different cloud?
Explore messaging guides for other cloud providers: