From 9a459b68c993891808aa1d277729f6b2ca73d884 Mon Sep 17 00:00:00 2001 From: YaroslavPshenichnikov Date: Fri, 1 Dec 2023 16:49:38 +0300 Subject: [PATCH] PREPARE for deployment --- docspace-reverse-proxy/index.mjs | 96 +++++++++---- main-template.yaml | 231 ++++++++++++++++++------------- 2 files changed, 199 insertions(+), 128 deletions(-) diff --git a/docspace-reverse-proxy/index.mjs b/docspace-reverse-proxy/index.mjs index 8a1ca76..d4b77c2 100644 --- a/docspace-reverse-proxy/index.mjs +++ b/docspace-reverse-proxy/index.mjs @@ -4,14 +4,32 @@ const cachedItem = {}; const regionsMap = { "default": "default_region_elb_placeholder", "eu-central-1": "eu_central_1_region_elb_placeholder", - "us-east-2": "us_east_2_region_elb_placeholder" + "us-west-2": "us_east_2_region_elb_placeholder" }; + const ddbRegionsMap = { - "default": "us-east-1", + + "default": "eu-central-1", + "us-east-1": "us-east-1", + "us-east-2": "us-east-2", + "us-west-1": "us-east-2", + "us-west-2": "us-east-2", + "eu-central-1": "eu-central-1", "eu-west-1": "eu-central-1", - "us-east-2": "us-east-2" + "eu-west-2": "eu-central-1", + "eu-west-3": "eu-central-1", + "eu-north-1": "eu-central-1", + "me-central-1": "eu-central-1", + + "ap-south-1": "ap-southeast-1", + "ap-northeast-3": "ap-southeast-1", + "ap-northeast-2": "ap-southeast-1", + "ap-southeast-1": "ap-southeast-1", + "ap-southeast-2": "ap-southeast-1", + "ap-northeast-1": "ap-southeast-1" + }; const dynamodbTableName = "dynamodb_table_name_placeholder"; @@ -28,7 +46,41 @@ if (ddbRegionsMap[execRegionCode]) { import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb"; -const ddbClient = new DynamoDBClient({ region: ddbClientRegion }); +async function getTenantRegion(ddbRegion, tenantDomain) { + + console.log("getTenantRegion params ddbRegion: %s, tenantDomain: %s", ddbRegion, tenantDomain); + + const ddbClient = new DynamoDBClient({ region: ddbRegion }); + + const getItemParams = { + Key: { + 'tenant_domain': { S: tenantDomain } + }, + ProjectionExpression: "tenant_region", + TableName: dynamodbTableName + }; + + console.log("[DynamoDb] before send command get item %s with tenant domain %s", getItemParams, tenantDomain); + + const response = await ddbClient.send(new GetItemCommand(getItemParams)); + + console.log("[DynamoDb] responce send command get item %s with tenant domain %s", response, tenantDomain); + + if (response && response.Item) { + + const tenantRegion = regionsMap[response.Item["tenant_region"]["S"]]; + + console.log("Added item %s to cache with key %s", tenantRegion, tenantDomain); + + return tenantRegion; + + } else { + + console.log("Error recieve data from DynamoDB with tenant domain %s in region %s", tenantDomain, ddbRegion); + + return null; + } +} export const handler = async (event, context, callback) => { console.log(JSON.stringify(event)); @@ -76,7 +128,6 @@ export const handler = async (event, context, callback) => { console.log("Register portal request: Change request origin to %s", originDomain); } - console.log("request after changed %s", JSON.stringify(request)); // Return to CloudFront @@ -91,39 +142,26 @@ export const handler = async (event, context, callback) => { } else { + originDomain = await getTenantRegion(ddbClientRegion, tenantDomain); - const getItemParams = { - Key: { - 'tenant_domain': { S: tenantDomain } - }, - ProjectionExpression: "tenant_region", - TableName: dynamodbTableName - }; - - console.log("[DynamoDb] before send command get item %s with tenant domain %s", getItemParams, tenantDomain); - - const responce = await ddbClient.send(new GetItemCommand(getItemParams)); - - console.log("[DynamoDb] responce send command get item %s with tenant domain %s", responce, tenantDomain); - - if (responce && responce.Item) { - - originDomain = regionsMap[responce.Item["tenant_region"]["S"]]; - - console.log("Added item %s to cache with key %s", originDomain, tenantDomain); - + if (originDomain == null) { - } else { + console.log("originDomain is null. Attempt 2. Trying get value from default region %s", ddbRegionsMap["default"]); - originDomain = regionsMap["default"]; + if (ddbRegionsMap["default"] != ddbClientRegion) { + originDomain = await getTenantRegion(ddbRegionsMap["default"], tenantDomain); + } - console.log("Error recieve data from DynamoDB with tenant domain %s", tenantDomain); + if (originDomain == null) { + console.log("originDomain is null. Using default"); + originDomain = regionsMap["default"]; + } } } cachedItem[tenantDomain] = { - expiresOn: Date.now() + 24 * 3600 * 1000, // Set expiry time of 24H + expiresOn: Date.now() + 15 * 60 * 1000, // Set expiry time of 15 minutes value: originDomain }; diff --git a/main-template.yaml b/main-template.yaml index f31960e..04d2dd9 100644 --- a/main-template.yaml +++ b/main-template.yaml @@ -29,105 +29,8 @@ Resources: SnapStart: ApplyOn: None PackageType: Zip - Policies: - - Statement: - - Action: - - dynamodb:* - - dax:* - - application-autoscaling:DeleteScalingPolicy - - application-autoscaling:DeregisterScalableTarget - - application-autoscaling:DescribeScalableTargets - - application-autoscaling:DescribeScalingActivities - - application-autoscaling:DescribeScalingPolicies - - application-autoscaling:PutScalingPolicy - - application-autoscaling:RegisterScalableTarget - - cloudwatch:DeleteAlarms - - cloudwatch:DescribeAlarmHistory - - cloudwatch:DescribeAlarms - - cloudwatch:DescribeAlarmsForMetric - - cloudwatch:GetMetricStatistics - - cloudwatch:ListMetrics - - cloudwatch:PutMetricAlarm - - cloudwatch:GetMetricData - - datapipeline:ActivatePipeline - - datapipeline:CreatePipeline - - datapipeline:DeletePipeline - - datapipeline:DescribeObjects - - datapipeline:DescribePipelines - - datapipeline:GetPipelineDefinition - - datapipeline:ListPipelines - - datapipeline:PutPipelineDefinition - - datapipeline:QueryObjects - - ec2:DescribeVpcs - - ec2:DescribeSubnets - - ec2:DescribeSecurityGroups - - iam:GetRole - - iam:ListRoles - - kms:DescribeKey - - kms:ListAliases - - sns:CreateTopic - - sns:DeleteTopic - - sns:ListSubscriptions - - sns:ListSubscriptionsByTopic - - sns:ListTopics - - sns:Subscribe - - sns:Unsubscribe - - sns:SetTopicAttributes - - lambda:CreateFunction - - lambda:ListFunctions - - lambda:ListEventSourceMappings - - lambda:CreateEventSourceMapping - - lambda:DeleteEventSourceMapping - - lambda:GetFunctionConfiguration - - lambda:DeleteFunction - - resource-groups:ListGroups - - resource-groups:ListGroupResources - - resource-groups:GetGroup - - resource-groups:GetGroupQuery - - resource-groups:DeleteGroup - - resource-groups:CreateGroup - - tag:GetResources - - kinesis:ListStreams - - kinesis:DescribeStream - - kinesis:DescribeStreamSummary - Effect: Allow - Resource: "*" - - Action: - - cloudwatch:GetInsightRuleReport - Effect: Allow - Resource: arn:aws:cloudwatch:*:*:insight-rule/DynamoDBContributorInsights* - - Action: - - iam:PassRole - Effect: Allow - Resource: "*" - Condition: - StringLike: - iam:PassedToService: - - application-autoscaling.amazonaws.com - - application-autoscaling.amazonaws.com.cn - - dax.amazonaws.com - - Effect: Allow - Action: - - iam:CreateServiceLinkedRole - Resource: "*" - Condition: - StringEquals: - iam:AWSServiceName: - - replication.dynamodb.amazonaws.com - - dax.amazonaws.com - - dynamodb.application-autoscaling.amazonaws.com - - contributorinsights.dynamodb.amazonaws.com - - kinesisreplication.dynamodb.amazonaws.com - - Effect: Allow - Action: - - logs:CreateLogGroup - Resource: arn:aws:logs:*:*:* - - Effect: Allow - Action: - - logs:CreateLogStream - - logs:PutLogEvents - Resource: - - arn:aws:logs:*:*:log-group:*:* + Role: !GetAtt DocspaceReverseProxyRole.Arn + GlobalDynamoDBTable: Type: AWS::DynamoDB::GlobalTable Properties: @@ -160,6 +63,13 @@ Resources: MaxCapacity: 10 TargetTrackingScalingPolicyConfiguration: TargetValue: 70 + - Region: ap-southeast-1 + ReadProvisionedThroughputSettings: + ReadCapacityAutoScalingSettings: + MinCapacity: 1 + MaxCapacity: 10 + TargetTrackingScalingPolicyConfiguration: + TargetValue: 70 WriteProvisionedThroughputSettings: WriteCapacityAutoScalingSettings: MinCapacity: 1 @@ -168,3 +78,126 @@ Resources: TargetValue: 70 StreamSpecification: StreamViewType: NEW_AND_OLD_IMAGES + + # ==== ROLES ==== # + DocspaceReverseProxyRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: sts:AssumeRole + Principal: + Service: + - "lambda.amazonaws.com" + - "edgelambda.amazonaws.com" + # ==== POLICIES ==== # + PublishLogsPolicy: + Type: AWS::IAM::ManagedPolicy + Properties: + Description: Allows functions to write logs + Roles: + - !Ref DocspaceReverseProxyRole + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: "*" + + DyanmoDBFullAccessPolicy: + Type: AWS::IAM::ManagedPolicy + Properties: + Description: Allows functions to write logs + Roles: + - !Ref DocspaceReverseProxyRole + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - dynamodb:* + - dax:* + - application-autoscaling:DeleteScalingPolicy + - application-autoscaling:DeregisterScalableTarget + - application-autoscaling:DescribeScalableTargets + - application-autoscaling:DescribeScalingActivities + - application-autoscaling:DescribeScalingPolicies + - application-autoscaling:PutScalingPolicy + - application-autoscaling:RegisterScalableTarget + - cloudwatch:DeleteAlarms + - cloudwatch:DescribeAlarmHistory + - cloudwatch:DescribeAlarms + - cloudwatch:DescribeAlarmsForMetric + - cloudwatch:GetMetricStatistics + - cloudwatch:ListMetrics + - cloudwatch:PutMetricAlarm + - cloudwatch:GetMetricData + - datapipeline:ActivatePipeline + - datapipeline:CreatePipeline + - datapipeline:DeletePipeline + - datapipeline:DescribeObjects + - datapipeline:DescribePipelines + - datapipeline:GetPipelineDefinition + - datapipeline:ListPipelines + - datapipeline:PutPipelineDefinition + - datapipeline:QueryObjects + - ec2:DescribeVpcs + - ec2:DescribeSubnets + - ec2:DescribeSecurityGroups + - iam:GetRole + - iam:ListRoles + - kms:DescribeKey + - kms:ListAliases + - sns:CreateTopic + - sns:DeleteTopic + - sns:ListSubscriptions + - sns:ListSubscriptionsByTopic + - sns:ListTopics + - sns:Subscribe + - sns:Unsubscribe + - sns:SetTopicAttributes + - lambda:CreateFunction + - lambda:ListFunctions + - lambda:ListEventSourceMappings + - lambda:CreateEventSourceMapping + - lambda:DeleteEventSourceMapping + - lambda:GetFunctionConfiguration + - lambda:DeleteFunction + - resource-groups:ListGroups + - resource-groups:ListGroupResources + - resource-groups:GetGroup + - resource-groups:GetGroupQuery + - resource-groups:DeleteGroup + - resource-groups:CreateGroup + - tag:GetResources + - kinesis:ListStreams + - kinesis:DescribeStream + - kinesis:DescribeStreamSummary + Resource: "*" + - Effect: Allow + Action: + - iam:PassRole + Condition: + StringLike: + iam:PassedToService: + - application-autoscaling.amazonaws.com + - application-autoscaling.amazonaws.com.cn + - dax.amazonaws.com + Resource: "*" + - Effect: Allow + Action: + - iam:CreateServiceLinkedRole + Condition: + StringEquals: + iam:AWSServiceName: + - replication.dynamodb.amazonaws.com + - dax.amazonaws.com + - dynamodb.application-autoscaling.amazonaws.com + - contributorinsights.dynamodb.amazonaws.com + - kinesisreplication.dynamodb.amazonaws.com + Resource: "*"