Last active
September 24, 2020 16:52
-
-
Save agonbina/b22f0a07442addf097ee7e18e612ff9f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
EventBridgeLambda, | |
EventsQueue, | |
FilterPolicyType, | |
getResourceNameWithPrefix, | |
LambdaFunction, | |
QueueLambda, | |
relativeRootPath, | |
SNSLambda | |
} from '@getcaya/infra' | |
import * as aws from '@pulumi/aws' | |
import * as pulumi from '@pulumi/pulumi' | |
import { envConfig, getEnvOrDefault } from './utils' | |
/** | |
* Globals | |
*/ | |
const namePrefix = `${pulumi.getProject()}-${pulumi.getStack()}` | |
const config = new pulumi.Config(pulumi.getProject()) | |
const chargebeeEventBridgeArn = pulumi.output( | |
// TODO: pass as config ? | |
new pulumi.StackReference(`AMN-DATA/platform-billing/${pulumi.getStack()}`).outputs['eventBridgeARN'] | |
) | |
const graphEventsSnsTopicName = getResourceNameWithPrefix('graph-events') | |
const graphEventsSnsTopic = aws.sns.Topic.get(graphEventsSnsTopicName, config.require('snsTopicEventsArn')) | |
/** | |
* node_modules lambda layer. We are going to re-use the same layer for every lambda. | |
*/ | |
const zipFile = relativeRootPath(config.require('nodeModulesPath')) | |
const nodeModuleLambdaLayerName = getResourceNameWithPrefix('lambda-layer-nodemodules') | |
const nodeModuleLambdaLayer = new aws.lambda.LayerVersion(nodeModuleLambdaLayerName, { | |
compatibleRuntimes: [aws.lambda.NodeJS12dXRuntime], | |
code: new pulumi.asset.FileArchive(zipFile), | |
layerName: nodeModuleLambdaLayerName | |
}) | |
/** | |
* Code archive | |
*/ | |
const code = new pulumi.asset.AssetArchive({ | |
'.': new pulumi.asset.FileArchive(relativeRootPath(config.require('functionsPath'))) | |
}) | |
/** | |
* Queues | |
*/ | |
const subscriptionPlanCreatedQueue = new EventsQueue({ | |
name: getResourceNameWithPrefix('subscription-plan-created-queue'), | |
topic: graphEventsSnsTopic, | |
filterPolicy: { | |
type: FilterPolicyType.SubscriptionPlan, | |
mutation: ['CREATED'] | |
}, | |
visibilityTimeoutSeconds: 60 | |
}) | |
const customerInfoUpdatedQueue = new EventsQueue({ | |
name: getResourceNameWithPrefix('customer-info-updated-queue'), | |
topic: graphEventsSnsTopic, | |
filterPolicy: { | |
type: FilterPolicyType.Customer, | |
mutation: ['UPDATED'], | |
updatedFields: ['firstName', 'lastName', 'companyName', 'email', 'phoneNumber'] | |
}, | |
visibilityTimeoutSeconds: 60 | |
}) | |
const customerScanCenterUpdatedQueue = new EventsQueue({ | |
name: getResourceNameWithPrefix('customer-scancenter-updated-queue'), | |
topic: graphEventsSnsTopic, | |
filterPolicy: { | |
type: FilterPolicyType.Customer, | |
mutation: ['UPDATED'], | |
updatedFields: ['scanCenter'] | |
} | |
}) | |
/** | |
* Lambdas | |
*/ | |
const scheduleReturnsQueueLambdaName = `${namePrefix}-schedule-returns` | |
const scheduleReturnsQueueLambda = new QueueLambda({ | |
name: scheduleReturnsQueueLambdaName, | |
layers: [nodeModuleLambdaLayer.arn], | |
code, | |
handler: 'build/functions/schedule-returns.handler', | |
queue: subscriptionPlanCreatedQueue.queue, | |
queueBatchSize: 1, | |
environment: { | |
...envConfig() | |
} | |
}) | |
const updateCustomerInfoToChargebeeLambdaName = `${namePrefix}-customerInfoToCB` | |
const updateCustomerInfoToChargebeeLambda = new QueueLambda({ | |
name: updateCustomerInfoToChargebeeLambdaName, | |
layers: [nodeModuleLambdaLayer.arn], | |
code, | |
handler: 'build/functions/customer/update-customer.handler', | |
queue: customerInfoUpdatedQueue.queue, | |
queueBatchSize: 1, | |
environment: { | |
...envConfig() | |
} | |
}) | |
const enableReturnsByScanCenterLambdaName = `${namePrefix}-enableReturns` | |
const enableReturnsByScanCenterLambda = new QueueLambda({ | |
name: enableReturnsByScanCenterLambdaName, | |
layers: [nodeModuleLambdaLayer.arn], | |
code, | |
handler: 'build/functions/customer/enable-returns-by-scancenter.handler', | |
queue: customerScanCenterUpdatedQueue.queue, | |
queueBatchSize: 1, | |
environment: { | |
...envConfig() | |
} | |
}) | |
const handleReturnsScheduleToggleLambdaName = `${namePrefix}-handleReturnsToggle` | |
const handleReturnsScheduleToggleLambda = new SNSLambda({ | |
name: handleReturnsScheduleToggleLambdaName, | |
description: 'Toggle scheduled moving of documents to(or from) the return basket', | |
layers: [nodeModuleLambdaLayer.arn], | |
code, | |
handler: 'build/functions/customer/handle-returns-schedule-toggle.handler', | |
topic: graphEventsSnsTopic, | |
snsFilterPolicy: { | |
type: FilterPolicyType.Customer, | |
mutation: ['UPDATED'], | |
updatedFields: ['returnsInterval'] | |
}, | |
timeout: 900, | |
environment: envConfig() | |
}) | |
const updateReturnAddressLambdaName = getResourceNameWithPrefix('updateReturnAddress') | |
const updateReturnAddressLambda = new EventBridgeLambda({ | |
name: updateReturnAddressLambdaName, | |
handler: 'build/functions/updateReturnAddress.handler', | |
code, | |
layers: [nodeModuleLambdaLayer.arn], | |
environment: { | |
...envConfig(), | |
SEGMENT_WRITE_KEY: getEnvOrDefault('SEGMENT_WRITE_KEY', 'o6g7lIhM5Y9ZwA5rzXxPLDqW2qk39RpB') | |
}, | |
eventBridgeArn: chargebeeEventBridgeArn, | |
eventPattern: { | |
source: ['chargebee.events.subscription_changed'] | |
} | |
}) | |
const customNotificationLambdaName = getResourceNameWithPrefix('customNotification') | |
const customNotificationLambda = new LambdaFunction({ | |
name: customNotificationLambdaName, | |
handler: 'build/functions/customer/custom-notification.handler', | |
runtime: aws.lambda.NodeJS12dXRuntime, | |
code, | |
layers: [nodeModuleLambdaLayer.arn], | |
environment: envConfig() | |
}) | |
const migrateAccountLambdaName = getResourceNameWithPrefix('migrateAccount') | |
const migrateAccountLambda = new LambdaFunction({ | |
name: migrateAccountLambdaName, | |
handler: 'build/functions/customer/migrate.handler', | |
runtime: aws.lambda.NodeJS12dXRuntime, | |
code, | |
layers: [nodeModuleLambdaLayer.arn], | |
environment: { | |
...envConfig(), | |
thundra_agent_lambda_trace_request_skip: 'true', | |
COGNITO_LEGACY_USER_POOL_ID: getEnvOrDefault('COGNITO_LEGACY_USER_POOL_ID', 'eu-central-1_sF6Y9OOZg'), | |
COGNITO_LEGACY_CLIENT_ID: getEnvOrDefault('COGNITO_LEGACY_CLIENT_ID', '2rs2mcch1k2hhk312croih12re') | |
} | |
}) | |
const setupCustomerLambdaName = getResourceNameWithPrefix('setupCustomer') | |
const setupCustomerLambda = new LambdaFunction({ | |
name: setupCustomerLambdaName, | |
handler: 'build/functions/customer/setup-customer.handler', | |
runtime: aws.lambda.NodeJS12dXRuntime, | |
code, | |
layers: [nodeModuleLambdaLayer.arn], | |
environment: envConfig() | |
}) | |
/** | |
* AWS Cognito Resources (Imported from serverless stack) | |
*/ | |
const isProduction = pulumi.getStack() === 'production' | |
const userPoolId = isProduction ? 'eu-central-1_3SDdDsA6m' : 'eu-central-1_XZTe0nEwq' | |
const cognitoUserPoolAccounts = new aws.cognito.UserPool( | |
getResourceNameWithPrefix('cognitoUserPoolAccounts'), | |
{ | |
name: `${pulumi.getStack()}-platform-accounts`, | |
adminCreateUserConfig: { | |
allowAdminCreateUserOnly: false | |
}, | |
aliasAttributes: ['preferred_username', 'email'], | |
autoVerifiedAttributes: ['email'], | |
emailConfiguration: { | |
emailSendingAccount: 'DEVELOPER', | |
sourceArn: 'arn:aws:ses:eu-west-1:420446605159:identity/[email protected]', | |
replyToEmailAddress: '[email protected]' | |
}, | |
mfaConfiguration: 'OFF', | |
passwordPolicy: { | |
minimumLength: 8, | |
requireLowercase: false, | |
requireNumbers: false, | |
requireSymbols: false, | |
requireUppercase: false, | |
temporaryPasswordValidityDays: 7 | |
}, | |
// TODO: to change the lamdas once the first time import is done. | |
lambdaConfig: { | |
preSignUp: isProduction | |
? 'arn:aws:lambda:eu-central-1:420446605159:function:platform-production-setupCustomer' | |
: 'arn:aws:lambda:eu-central-1:420446605159:function:platform-testing-setupCustomer', | |
customMessage: isProduction | |
? 'arn:aws:lambda:eu-central-1:420446605159:function:platform-production-customNotification' | |
: 'arn:aws:lambda:eu-central-1:420446605159:function:platform-testing-customNotification', | |
...(isProduction | |
? { userMigration: 'arn:aws:lambda:eu-central-1:420446605159:function:platform-production-migrateAccount' } | |
: {}) | |
}, | |
...(isProduction | |
? { | |
userPoolAddOns: { advancedSecurityMode: 'AUDIT' } | |
} | |
: {}) | |
}, | |
{ | |
import: userPoolId | |
} | |
) | |
const setupCustomerLambdaPermission = new aws.lambda.Permission( | |
getResourceNameWithPrefix('setupCustomerLambdaPermission'), | |
{ | |
function: setupCustomerLambda.lambda, | |
action: 'lambda:InvokeFunction', | |
principal: 'cognito-idp.amazonaws.com', | |
sourceArn: cognitoUserPoolAccounts.arn | |
} | |
) | |
const customNotificationLambdaPermission = new aws.lambda.Permission( | |
getResourceNameWithPrefix('customNotificationLambdaPermission'), | |
{ | |
function: customNotificationLambda.lambda, | |
action: 'lambda:InvokeFunction', | |
principal: 'cognito-idp.amazonaws.com', | |
sourceArn: cognitoUserPoolAccounts.arn | |
} | |
) | |
if (isProduction) { | |
const migrateAccountLambdaPermission = new aws.lambda.Permission( | |
getResourceNameWithPrefix('migrateAccountLambdaPermission'), | |
{ | |
function: migrateAccountLambda.lambda, | |
action: 'lambda:InvokeFunction', | |
principal: 'cognito-idp.amazonaws.com', | |
sourceArn: cognitoUserPoolAccounts.arn | |
} | |
) | |
} | |
const mobileClientId = isProduction ? '1mb87qq2cblf02899skttkc1i7' : '1lnvudc1rm1s633sbe4ii1lkr0' | |
const cognitoUserPoolClientMobileApp = new aws.cognito.UserPoolClient( | |
getResourceNameWithPrefix('UserPoolClientMobileApp'), | |
{ | |
name: 'Mobile App', | |
explicitAuthFlows: ['USER_PASSWORD_AUTH'], | |
readAttributes: ['email'], | |
writeAttributes: ['email'], | |
refreshTokenValidity: 30, | |
userPoolId: cognitoUserPoolAccounts.id | |
}, | |
{ | |
parent: cognitoUserPoolAccounts, | |
import: `${userPoolId}/${mobileClientId}` | |
} | |
) | |
const webAppClientId = isProduction ? 'smi9060mf6k8oee4ainard6g5' : '7rbudv7odaunt3b6vsiepfdsnc' | |
const cognitoUserPoolClientWebApp = new aws.cognito.UserPoolClient( | |
getResourceNameWithPrefix('UserPoolClientWebApp'), | |
{ | |
name: 'Web App', | |
explicitAuthFlows: ['USER_PASSWORD_AUTH'], | |
readAttributes: ['email'], | |
writeAttributes: ['email'], | |
refreshTokenValidity: 30, | |
userPoolId: cognitoUserPoolAccounts.id | |
}, | |
{ | |
parent: cognitoUserPoolAccounts, | |
import: `${userPoolId}/${webAppClientId}` | |
} | |
) | |
const alexaClientAppId = isProduction ? 's8iaiu1r1allrdb7o93tsklb2' : '6r3icoecfo9fn13ns1jr1ufdd1' | |
const cognitoUserPoolClientAlexaApp = new aws.cognito.UserPoolClient( | |
getResourceNameWithPrefix('UserPoolAlexaSkillApp'), | |
{ | |
name: 'Alexa', | |
explicitAuthFlows: [], | |
readAttributes: ['email_verified', 'email'], | |
refreshTokenValidity: 30, | |
userPoolId: cognitoUserPoolAccounts.id, | |
supportedIdentityProviders: ['COGNITO'], | |
callbackUrls: isProduction | |
? [ | |
'https://alexa.amazon.co.jp/api/skill/link/M3AX6CFJ15WDFG', | |
'https://layla.amazon.com/api/skill/link/M3AX6CFJ15WDFG', | |
'https://pitangui.amazon.com/api/skill/link/M3AX6CFJ15WDFG' | |
] | |
: [ | |
'https://layla.amazon.com/api/skill/link/MS2F2Z51OLZMY', | |
'https://pitangui.amazon.com/api/skill/link/MS2F2Z51OLZMY' | |
], | |
allowedOauthFlows: ['code', 'implicit'], | |
allowedOauthFlowsUserPoolClient: true, | |
allowedOauthScopes: ['openid', 'email'] | |
}, | |
{ | |
parent: cognitoUserPoolAccounts, | |
import: `${userPoolId}/${alexaClientAppId}` | |
} | |
) | |
/** | |
* Outputs | |
*/ | |
export const userPoolAccountsId = cognitoUserPoolAccounts.id | |
export const userPoolWebAppClientId = cognitoUserPoolClientWebApp.id | |
export const userPoolMobileAppClientId = cognitoUserPoolClientMobileApp.id | |
export const userPoolAlexaAppClientId = cognitoUserPoolClientAlexaApp.id |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment