From 1ebaf523840e5e29d4993188874e52b8c9b290f4 Mon Sep 17 00:00:00 2001 From: Kazuki Matsuda Date: Sun, 2 Jul 2023 14:30:03 +0900 Subject: [PATCH 1/3] feat: use ha option to create db --- src/supabase-db/index.ts | 11 ++++++++--- src/supabase-stack.ts | 15 ++++++++++++++- test/__snapshots__/main.test.ts.snap | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/supabase-db/index.ts b/src/supabase-db/index.ts index 36d900b..1c1802e 100644 --- a/src/supabase-db/index.ts +++ b/src/supabase-db/index.ts @@ -16,6 +16,7 @@ const excludeCharacters = '%+~`#$&*()|[]{}:;<>?!\'/@\"\\=^,'; // for Password interface SupabaseDatabaseProps { vpc: ec2.IVpc; + highAvailability?: cdk.CfnCondition; } export class SupabaseDatabase extends Construct { @@ -31,7 +32,7 @@ export class SupabaseDatabase extends Construct { constructor(scope: Construct, id: string, props: SupabaseDatabaseProps) { super(scope, id); - const { vpc } = props; + const { vpc, highAvailability } = props; /** Database Engine */ //const engine = rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_15 }); @@ -65,8 +66,12 @@ export class SupabaseDatabase extends Construct { storageEncrypted: true, }); + const instance1 = this.cluster.node.findChild('Instance1').node.defaultChild as rds.CfnDBInstance; + const instance2 = this.cluster.node.findChild('Instance2').node.defaultChild as rds.CfnDBInstance; - const dbInstance = this.cluster.node.findChild('Instance1') as rds.CfnDBInstance; + if (typeof highAvailability !== 'undefined') { + instance2.cfnOptions.condition = highAvailability; + } //this.instance = new rds.DatabaseInstance(this, 'Instance', { // engine, @@ -137,7 +142,7 @@ export class SupabaseDatabase extends Construct { }); // Wait until the database is ready. - this.migration.node.addDependency(dbInstance); + this.migration.node.addDependency(instance1); /** Custom resource handler to modify db user password */ const userPasswordFunction = new NodejsFunction(this, 'UserPasswordFunction', { diff --git a/src/supabase-stack.ts b/src/supabase-stack.ts index d90b445..7f8fbce 100644 --- a/src/supabase-stack.ts +++ b/src/supabase-stack.ts @@ -124,6 +124,16 @@ export class SupabaseStack extends FargateStack { description: 'https://gallery.ecr.aws/supabase/postgres-meta', }); + /** The flag for High Availability */ + const enableHA = new cdk.CfnParameter(this, 'EnableHighAvailability', { + description: 'Enable auto-scaling and clustering (Multi-AZ).', + type: 'String', + default: 'false', + allowedValues: ['true', 'false'], + }); + /** CFn condition for High Availability */ + const highAvailability = new cdk.CfnCondition(this, 'HighAvailability', { expression: cdk.Fn.conditionEquals(enableHA, 'true') }); + /** The minimum number of aurora capacity units */ const minACU = new cdk.CfnParameter(this, 'MinACU', { description: 'The minimum number of Aurora capacity units (ACU) for a DB instance in an Aurora Serverless v2 cluster.', @@ -187,7 +197,10 @@ export class SupabaseStack extends FargateStack { }); /** PostgreSQL Database with Secrets */ - const db = new SupabaseDatabase(this, 'Database', { vpc }); + const db = new SupabaseDatabase(this, 'Database', { + vpc, + highAvailability, + }); /** SMTP Credentials */ const smtp = new SesSmtp(this, 'Smtp', { diff --git a/test/__snapshots__/main.test.ts.snap b/test/__snapshots__/main.test.ts.snap index 8ca9ec8..2c253fb 100644 --- a/test/__snapshots__/main.test.ts.snap +++ b/test/__snapshots__/main.test.ts.snap @@ -63,6 +63,14 @@ Object { "0", ], }, + "HighAvailability": Object { + "Fn::Equals": Array [ + Object { + "Ref": "EnableHighAvailability", + }, + "true", + ], + }, "ImgproxyServiceDisabledE6934A15": Object { "Fn::Equals": Array [ Object { @@ -924,6 +932,15 @@ Object { "Description": "This is the email address the emails are sent from. If Amazon WorkMail is enabled, it set \\"noreply@supabase-.awsapps.com\\"", "Type": "String", }, + "EnableHighAvailability": Object { + "AllowedValues": Array [ + "true", + "false", + ], + "Default": "false", + "Description": "Enable auto-scaling and clustering (Multi-AZ).", + "Type": "String", + }, "EnableWorkMail": Object { "AllowedValues": Array [ "true", @@ -3551,6 +3568,7 @@ Object { "UpdateReplacePolicy": "Delete", }, "DatabaseClusterInstance2D6BCD1AC": Object { + "Condition": "HighAvailability", "DeletionPolicy": "Delete", "DependsOn": Array [ "VPCPrivateSubnet1DefaultRouteAE1D6490", From e46c7dcc3f8cb2f3b613e34ef07c7dad33d6b33b Mon Sep 17 00:00:00 2001 From: Kazuki Matsuda Date: Sun, 2 Jul 2023 22:08:00 +0900 Subject: [PATCH 2/3] feat: use HA option to create ECS service --- src/ecs-patterns.ts | 74 ++-- src/supabase-db/index.ts | 2 +- src/supabase-stack.ts | 151 ++----- test/__snapshots__/main.test.ts.snap | 573 +++++++++++---------------- 4 files changed, 318 insertions(+), 482 deletions(-) diff --git a/src/ecs-patterns.ts b/src/ecs-patterns.ts index 58deb3a..befc45f 100644 --- a/src/ecs-patterns.ts +++ b/src/ecs-patterns.ts @@ -1,4 +1,5 @@ import * as cdk from 'aws-cdk-lib'; +import { ScalableTarget, CfnScalableTarget, CfnScalingPolicy } from 'aws-cdk-lib/aws-applicationautoscaling'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; import * as ecs from 'aws-cdk-lib/aws-ecs'; import { NetworkLoadBalancedTaskImageOptions } from 'aws-cdk-lib/aws-ecs-patterns'; @@ -8,7 +9,6 @@ import * as logs from 'aws-cdk-lib/aws-logs'; import * as cloudMap from 'aws-cdk-lib/aws-servicediscovery'; import { Construct } from 'constructs'; import { AuthProvider } from './supabase-auth-provider'; -import { SupabaseDatabase } from './supabase-db'; import { FargateStack } from './supabase-stack'; interface SupabaseTaskImageOptions extends NetworkLoadBalancedTaskImageOptions { @@ -30,6 +30,7 @@ export interface BaseFargateServiceProps { export interface AutoScalingFargateServiceProps extends BaseFargateServiceProps { minTaskCount?: number; maxTaskCount?: number; + highAvailability?: cdk.CfnCondition; } export interface TargetGroupProps { @@ -162,49 +163,32 @@ export class BaseFargateService extends Construct { } export class AutoScalingFargateService extends BaseFargateService { - readonly cfnParameters: { - taskSize: cdk.CfnParameter; - minTaskCount: cdk.CfnParameter; - maxTaskCount: cdk.CfnParameter; - }; + readonly taskSize: cdk.CfnParameter; + constructor(scope: FargateStack, id: string, props: AutoScalingFargateServiceProps) { super(scope, id, props); - const { minTaskCount, maxTaskCount } = props; - - this.cfnParameters = { - taskSize: new cdk.CfnParameter(this, 'TaskSize', { - description: 'Fargare task size', - type: 'String', - default: 'micro', - allowedValues: ['micro', 'small', 'medium', 'large', 'xlarge', '2xlarge', '4xlarge'], - }), - minTaskCount: new cdk.CfnParameter(this, 'MinTaskCount', { - description: 'Minimum fargate task count', - type: 'Number', - default: (typeof minTaskCount == 'undefined') ? 1 : minTaskCount, - minValue: 0, - }), - maxTaskCount: new cdk.CfnParameter(this, 'MaxTaskCount', { - description: 'Maximum fargate task count', - type: 'Number', - default: (typeof maxTaskCount == 'undefined') ? 20 : maxTaskCount, - minValue: 0, - }), - }; - - const cpu = scope.taskSizeMapping.findInMap(this.cfnParameters.taskSize.valueAsString, 'cpu'); - const memory = scope.taskSizeMapping.findInMap(this.cfnParameters.taskSize.valueAsString, 'memory'); - - (this.service.taskDefinition.node.defaultChild as ecs.CfnTaskDefinition).addPropertyOverride('Cpu', cpu); - (this.service.taskDefinition.node.defaultChild as ecs.CfnTaskDefinition).addPropertyOverride('Memory', memory); - - const serviceDisabled = new cdk.CfnCondition(this, 'ServiceDisabled', { expression: cdk.Fn.conditionEquals(this.cfnParameters.minTaskCount, '0') }); - (this.service.node.defaultChild as ecs.CfnService).addPropertyOverride('DesiredCount', cdk.Fn.conditionIf(serviceDisabled.logicalId, 0, cdk.Aws.NO_VALUE)); + const { minTaskCount, maxTaskCount, highAvailability } = props; + + this.taskSize = new cdk.CfnParameter(this, 'TaskSize', { + description: 'Fargare task size', + type: 'String', + default: 'medium', + allowedValues: ['none', 'micro', 'small', 'medium', 'large', 'xlarge', '2xlarge', '4xlarge'], + }); + + /** CFn task definition to override */ + const taskDef = this.service.taskDefinition.node.defaultChild as ecs.CfnTaskDefinition; + + const cpu = scope.taskSizeMapping.findInMap(this.taskSize.valueAsString, 'cpu'); + const memory = scope.taskSizeMapping.findInMap(this.taskSize.valueAsString, 'memory'); + + taskDef.addPropertyOverride('Cpu', cpu); + taskDef.addPropertyOverride('Memory', memory); const autoScaling = this.service.autoScaleTaskCount({ - minCapacity: this.cfnParameters.minTaskCount.valueAsNumber, - maxCapacity: this.cfnParameters.maxTaskCount.valueAsNumber, + minCapacity: minTaskCount ?? 2, + maxCapacity: maxTaskCount ?? 20, }); autoScaling.scaleOnCpuUtilization('ScaleOnCpu', { @@ -212,5 +196,17 @@ export class AutoScalingFargateService extends BaseFargateService { scaleInCooldown: cdk.Duration.seconds(60), scaleOutCooldown: cdk.Duration.seconds(60), }); + + /** CFn condition for ECS service */ + const serviceEnabled = new cdk.CfnCondition(this, 'ServiceEnabled', { expression: cdk.Fn.conditionNot(cdk.Fn.conditionEquals(this.taskSize, 'none')) }); + (this.service.node.defaultChild as ecs.CfnService).addPropertyOverride('DesiredCount', cdk.Fn.conditionIf(serviceEnabled.logicalId, cdk.Aws.NO_VALUE, 0)); + + if (typeof highAvailability != 'undefined') { + /** CFn condition for auto-scaling */ + const autoScalingEnabled = new cdk.CfnCondition(this, 'AutoScalingEnabled', { expression: cdk.Fn.conditionAnd(serviceEnabled, highAvailability) }); + const target = autoScaling.node.findChild('Target') as ScalableTarget; + (target.node.defaultChild as CfnScalableTarget).cfnOptions.condition = autoScalingEnabled; + (target.node.findChild('ScaleOnCpu').node.defaultChild as CfnScalingPolicy).cfnOptions.condition = autoScalingEnabled; + } } } diff --git a/src/supabase-db/index.ts b/src/supabase-db/index.ts index 1c1802e..8059d8e 100644 --- a/src/supabase-db/index.ts +++ b/src/supabase-db/index.ts @@ -70,7 +70,7 @@ export class SupabaseDatabase extends Construct { const instance2 = this.cluster.node.findChild('Instance2').node.defaultChild as rds.CfnDBInstance; if (typeof highAvailability !== 'undefined') { - instance2.cfnOptions.condition = highAvailability; + instance2.cfnOptions.condition = highAvailability; } //this.instance = new rds.DatabaseInstance(this, 'Instance', { diff --git a/src/supabase-stack.ts b/src/supabase-stack.ts index 7f8fbce..583cb80 100644 --- a/src/supabase-stack.ts +++ b/src/supabase-stack.ts @@ -26,6 +26,7 @@ export class FargateStack extends cdk.Stack { this.taskSizeMapping = new cdk.CfnMapping(this, 'TaskSize', { mapping: { + 'none': { cpu: 256, memory: 1024 }, 'micro': { cpu: 256, memory: 1024 }, 'small': { cpu: 512, memory: 1024 }, 'medium': { cpu: 1024, memory: 2048 }, @@ -125,14 +126,14 @@ export class SupabaseStack extends FargateStack { }); /** The flag for High Availability */ - const enableHA = new cdk.CfnParameter(this, 'EnableHighAvailability', { + const enableHighAvailability = new cdk.CfnParameter(this, 'EnableHighAvailability', { description: 'Enable auto-scaling and clustering (Multi-AZ).', type: 'String', default: 'false', allowedValues: ['true', 'false'], }); /** CFn condition for High Availability */ - const highAvailability = new cdk.CfnCondition(this, 'HighAvailability', { expression: cdk.Fn.conditionEquals(enableHA, 'true') }); + const highAvailability = new cdk.CfnCondition(this, 'HighAvailability', { expression: cdk.Fn.conditionEquals(enableHighAvailability, 'true') }); /** The minimum number of aurora capacity units */ const minACU = new cdk.CfnParameter(this, 'MinACU', { @@ -292,6 +293,7 @@ export class SupabaseStack extends FargateStack { SERVICE_KEY: ecs.Secret.fromSsmParameter(serviceRoleKey.ssmParameter), }, }, + highAvailability, }); /** TargetGroup for kong-gateway */ @@ -371,6 +373,7 @@ export class SupabaseStack extends FargateStack { GOTRUE_SMTP_PASS: ecs.Secret.fromSecretsManager(smtp.secret, 'password'), }, }, + highAvailability, }); const authProviders = auth.addExternalAuthProviders(`${apiExternalUrl}/auth/v1/callback`, 3); @@ -390,6 +393,7 @@ export class SupabaseStack extends FargateStack { PGRST_JWT_SECRET: ecs.Secret.fromSecretsManager(jwtSecret), }, }, + highAvailability, }); /** GraphQL API for any PostgreSQL Database */ @@ -415,6 +419,7 @@ export class SupabaseStack extends FargateStack { JWT_SECRET: ecs.Secret.fromSecretsManager(jwtSecret), }, }, + highAvailability, }); /** Secret used by the server to sign cookies. Recommended: 64 characters. */ @@ -455,6 +460,7 @@ export class SupabaseStack extends FargateStack { entryPoint: ['/usr/bin/tini', '-s', '-g', '--'], // ignore /app/limits.sh command: ['sh', '-c', '/app/bin/migrate && /app/bin/realtime eval "Realtime.Release.seeds(Realtime.Repo)" && /app/bin/server'], }, + highAvailability, }); // Wait until the database migration is complete. @@ -492,6 +498,7 @@ export class SupabaseStack extends FargateStack { IMGPROXY_ENABLE_WEBP_DETECTION: 'true', }, }, + highAvailability, }); /** S3 compatible object storage API that stores metadata in Postgres */ @@ -534,6 +541,7 @@ export class SupabaseStack extends FargateStack { }, }, cpuArchitecture: 'X86_64', // storage-api does not work on ARM64 + highAvailability, }); // Allow storage-api to read and write to the bucket @@ -556,6 +564,7 @@ export class SupabaseStack extends FargateStack { PG_META_DB_PASSWORD: ecs.Secret.fromSecretsManager(supabaseAdminSecret, 'password'), }, }, + highAvailability, }); // Wait until the database migration is complete. @@ -662,7 +671,7 @@ export class SupabaseStack extends FargateStack { ], }, { - Label: { default: 'Supabase - Auth E-mail Settings' }, + Label: { default: 'Supabase - SMTP Settings' }, Parameters: [ senderEmail.logicalId, senderName.logicalId, @@ -671,7 +680,7 @@ export class SupabaseStack extends FargateStack { ], }, { - Label: { default: 'Supabase - Container Image URIs' }, + Label: { default: 'Supabase - Versions (Container Images)' }, Parameters: [ authImageUri.logicalId, restImageUri.logicalId, @@ -683,80 +692,30 @@ export class SupabaseStack extends FargateStack { ], }, { - Label: { default: 'Infrastructure Settings - Database' }, - Parameters: [ - minACU.logicalId, - maxACU.logicalId, - ], - }, - { - Label: { default: 'Infrastructure Settings - Security' }, + Label: { default: 'Infrastructure Settings' }, Parameters: [ + enableHighAvailability.logicalId, cdn.cfnParameters.webAclArn.logicalId, ], }, { - Label: { default: 'Infrastructure Settings - Kong (API Gateway)' }, - Parameters: [ - kong.cfnParameters.taskSize.logicalId, - kong.cfnParameters.minTaskCount.logicalId, - kong.cfnParameters.maxTaskCount.logicalId, - ], - }, - { - Label: { default: 'Infrastructure Settings - Auth API (GoTrue)' }, - Parameters: [ - auth.cfnParameters.taskSize.logicalId, - auth.cfnParameters.minTaskCount.logicalId, - auth.cfnParameters.maxTaskCount.logicalId, - ], - }, - { - Label: { default: 'Infrastructure Settings - RESTful API (PostgREST)' }, - Parameters: [ - rest.cfnParameters.taskSize.logicalId, - rest.cfnParameters.minTaskCount.logicalId, - rest.cfnParameters.maxTaskCount.logicalId, - ], - }, - { - Label: { default: 'Infrastructure Settings - GraphQL API (PostGraphile)' }, - Parameters: [ - gql.cfnParameters.taskSize.logicalId, - gql.cfnParameters.minTaskCount.logicalId, - gql.cfnParameters.maxTaskCount.logicalId, - ], - }, - { - Label: { default: 'Infrastructure Settings - Realtime API' }, - Parameters: [ - realtime.cfnParameters.taskSize.logicalId, - realtime.cfnParameters.minTaskCount.logicalId, - realtime.cfnParameters.maxTaskCount.logicalId, - ], - }, - { - Label: { default: 'Infrastructure Settings - Storage API' }, - Parameters: [ - storage.cfnParameters.taskSize.logicalId, - storage.cfnParameters.minTaskCount.logicalId, - storage.cfnParameters.maxTaskCount.logicalId, - ], - }, - { - Label: { default: 'Infrastructure Settings - Imgproxy' }, + Label: { default: 'Infrastructure Settings - Database' }, Parameters: [ - imgproxy.cfnParameters.taskSize.logicalId, - imgproxy.cfnParameters.minTaskCount.logicalId, - imgproxy.cfnParameters.maxTaskCount.logicalId, + minACU.logicalId, + maxACU.logicalId, ], }, { - Label: { default: 'Infrastructure Settings - Postgres Meta API' }, + Label: { default: 'Infrastructure Settings - Containers' }, Parameters: [ - meta.cfnParameters.taskSize.logicalId, - meta.cfnParameters.minTaskCount.logicalId, - meta.cfnParameters.maxTaskCount.logicalId, + kong.taskSize.logicalId, + auth.taskSize.logicalId, + rest.taskSize.logicalId, + gql.taskSize.logicalId, + realtime.taskSize.logicalId, + storage.taskSize.logicalId, + imgproxy.taskSize.logicalId, + meta.taskSize.logicalId, ], }, ], @@ -771,49 +730,27 @@ export class SupabaseStack extends FargateStack { [sesRegion.logicalId]: { default: 'Amazon SES Region' }, [enableWorkMail.logicalId]: { default: 'Enable Test E-mail Domain (via Amazon WorkMail)' }, - [authImageUri.logicalId]: { default: 'Auth API Image URI - GoTrue' }, - [restImageUri.logicalId]: { default: 'Rest API Image URI - PostgREST' }, - [realtimeImageUri.logicalId]: { default: 'Realtime API Image URI' }, - [storageImageUri.logicalId]: { default: 'Storage API Image URI' }, - [imgproxyImageUri.logicalId]: { default: 'Imgproxy Image URI' }, - [postgresMetaImageUri.logicalId]: { default: 'Postgres Meta API Image URI' }, - - [minACU.logicalId]: { default: 'Minimum ACUs' }, - [maxACU.logicalId]: { default: 'Maximum ACUs' }, + [authImageUri.logicalId]: { default: 'Image URI - GoTrue' }, + [restImageUri.logicalId]: { default: 'Image URI - PostgREST' }, + [realtimeImageUri.logicalId]: { default: 'Image URI - Realtime' }, + [storageImageUri.logicalId]: { default: 'Image URI - Storage' }, + [imgproxyImageUri.logicalId]: { default: 'Image URI - imgproxy' }, + [postgresMetaImageUri.logicalId]: { default: 'Image URI - postgres-meta' }, + [enableHighAvailability.logicalId]: { default: 'High Availability (HA)' }, [cdn.cfnParameters.webAclArn.logicalId]: { default: 'Web ACL ARN (AWS WAF)' }, - [kong.cfnParameters.taskSize.logicalId]: { default: 'Fargate Task Size' }, - [kong.cfnParameters.minTaskCount.logicalId]: { default: 'Minimum Fargate Task Count' }, - [kong.cfnParameters.maxTaskCount.logicalId]: { default: 'Maximum Fargate Task Count' }, - - [auth.cfnParameters.taskSize.logicalId]: { default: 'Fargate Task Size' }, - [auth.cfnParameters.minTaskCount.logicalId]: { default: 'Minimum Fargate Task Count' }, - [auth.cfnParameters.maxTaskCount.logicalId]: { default: 'Maximum Fargate Task Count' }, - - [rest.cfnParameters.taskSize.logicalId]: { default: 'Fargate Task Size' }, - [rest.cfnParameters.minTaskCount.logicalId]: { default: 'Minimum Fargate Task Count' }, - [rest.cfnParameters.maxTaskCount.logicalId]: { default: 'Maximum Fargate Task Count' }, - - [gql.cfnParameters.taskSize.logicalId]: { default: 'Fargate Task Size' }, - [gql.cfnParameters.minTaskCount.logicalId]: { default: 'Minimum Fargate Task Count' }, - [gql.cfnParameters.maxTaskCount.logicalId]: { default: 'Maximum Fargate Task Count' }, - - [realtime.cfnParameters.taskSize.logicalId]: { default: 'Fargate Task Size' }, - [realtime.cfnParameters.minTaskCount.logicalId]: { default: 'Minimum Fargate Task Count' }, - [realtime.cfnParameters.maxTaskCount.logicalId]: { default: 'Maximum Fargate Task Count' }, - - [storage.cfnParameters.taskSize.logicalId]: { default: 'Fargate Task Size' }, - [storage.cfnParameters.minTaskCount.logicalId]: { default: 'Minimum Fargate Task Count' }, - [storage.cfnParameters.maxTaskCount.logicalId]: { default: 'Maximum Fargate Task Count' }, - - [imgproxy.cfnParameters.taskSize.logicalId]: { default: 'Fargate Task Size' }, - [imgproxy.cfnParameters.minTaskCount.logicalId]: { default: 'Minimum Fargate Task Count' }, - [imgproxy.cfnParameters.maxTaskCount.logicalId]: { default: 'Maximum Fargate Task Count' }, + [minACU.logicalId]: { default: 'Minimum ACUs' }, + [maxACU.logicalId]: { default: 'Maximum ACUs' }, - [meta.cfnParameters.taskSize.logicalId]: { default: 'Fargate Task Size' }, - [meta.cfnParameters.minTaskCount.logicalId]: { default: 'Minimum Fargate Task Count' }, - [meta.cfnParameters.maxTaskCount.logicalId]: { default: 'Maximum Fargate Task Count' }, + [kong.taskSize.logicalId]: { default: 'Task Size - Kong' }, + [auth.taskSize.logicalId]: { default: 'Task Size - GoTrue' }, + [rest.taskSize.logicalId]: { default: 'Task Size - PostgREST' }, + [gql.taskSize.logicalId]: { default: 'Task Size - PostGraphile' }, + [realtime.taskSize.logicalId]: { default: 'Task Size - Realtime' }, + [storage.taskSize.logicalId]: { default: 'Task Size - Storage' }, + [imgproxy.taskSize.logicalId]: { default: 'Task Size - imgproxy' }, + [meta.taskSize.logicalId]: { default: 'Task Size - postgres-meta' }, [studioBranch.logicalId]: { default: 'Supabase Studio Branch' }, }, diff --git a/test/__snapshots__/main.test.ts.snap b/test/__snapshots__/main.test.ts.snap index 2c253fb..1e85117 100644 --- a/test/__snapshots__/main.test.ts.snap +++ b/test/__snapshots__/main.test.ts.snap @@ -3,6 +3,16 @@ exports[`Snapshot 1`] = ` Object { "Conditions": Object { + "AuthAutoScalingEnabled0CD7354E": Object { + "Fn::And": Array [ + Object { + "Condition": "AuthServiceEnabled3234D87F", + }, + Object { + "Condition": "HighAvailability", + }, + ], + }, "AuthProvider1Enabled983DA6B5": Object { "Fn::Not": Array [ Object { @@ -39,12 +49,16 @@ Object { }, ], }, - "AuthServiceDisabledB6209B31": Object { - "Fn::Equals": Array [ + "AuthServiceEnabled3234D87F": Object { + "Fn::Not": Array [ Object { - "Ref": "AuthMinTaskCount998F20C4", + "Fn::Equals": Array [ + Object { + "Ref": "AuthTaskSize9895C206", + }, + "none", + ], }, - "0", ], }, "CdnWebAclUndefinedCAA325A4": Object { @@ -55,12 +69,26 @@ Object { "", ], }, - "GraphQLServiceDisabled2040BDFB": Object { - "Fn::Equals": Array [ + "GraphQLAutoScalingEnabled686BA277": Object { + "Fn::And": Array [ + Object { + "Condition": "GraphQLServiceEnabledC2BD6E3B", + }, Object { - "Ref": "GraphQLMinTaskCount0807D92D", + "Condition": "HighAvailability", + }, + ], + }, + "GraphQLServiceEnabledC2BD6E3B": Object { + "Fn::Not": Array [ + Object { + "Fn::Equals": Array [ + Object { + "Ref": "GraphQLTaskSize228AD0D2", + }, + "none", + ], }, - "0", ], }, "HighAvailability": Object { @@ -71,52 +99,136 @@ Object { "true", ], }, - "ImgproxyServiceDisabledE6934A15": Object { - "Fn::Equals": Array [ + "ImgproxyAutoScalingEnabled44E9E87F": Object { + "Fn::And": Array [ Object { - "Ref": "ImgproxyMinTaskCount7B881431", + "Condition": "ImgproxyServiceEnabled64E773FC", + }, + Object { + "Condition": "HighAvailability", }, - "0", ], }, - "KongServiceDisabled5CB631B8": Object { - "Fn::Equals": Array [ + "ImgproxyServiceEnabled64E773FC": Object { + "Fn::Not": Array [ Object { - "Ref": "KongMinTaskCount4451EF4C", + "Fn::Equals": Array [ + Object { + "Ref": "ImgproxyTaskSize5D0DD9F6", + }, + "none", + ], }, - "0", ], }, - "MetaServiceDisabled3B808F33": Object { - "Fn::Equals": Array [ + "KongAutoScalingEnabled41DC2F80": Object { + "Fn::And": Array [ Object { - "Ref": "MetaMinTaskCountEA12F444", + "Condition": "KongServiceEnabled5CB62A18", + }, + Object { + "Condition": "HighAvailability", }, - "0", ], }, - "RealtimeServiceDisabledD3DB8A99": Object { - "Fn::Equals": Array [ + "KongServiceEnabled5CB62A18": Object { + "Fn::Not": Array [ Object { - "Ref": "RealtimeMinTaskCount306F67E8", + "Fn::Equals": Array [ + Object { + "Ref": "KongTaskSize93C195E9", + }, + "none", + ], }, - "0", ], }, - "RestServiceDisabled280508EE": Object { - "Fn::Equals": Array [ + "MetaAutoScalingEnabledCF28EDB1": Object { + "Fn::And": Array [ + Object { + "Condition": "MetaServiceEnabled094DCF06", + }, Object { - "Ref": "RestMinTaskCount073959EA", + "Condition": "HighAvailability", }, - "0", ], }, - "StorageServiceDisabled05C15E2C": Object { - "Fn::Equals": Array [ + "MetaServiceEnabled094DCF06": Object { + "Fn::Not": Array [ Object { - "Ref": "StorageMinTaskCount07E65703", + "Fn::Equals": Array [ + Object { + "Ref": "MetaTaskSize556D36D9", + }, + "none", + ], + }, + ], + }, + "RealtimeAutoScalingEnabled7991ED3B": Object { + "Fn::And": Array [ + Object { + "Condition": "RealtimeServiceEnabled18ED891C", + }, + Object { + "Condition": "HighAvailability", + }, + ], + }, + "RealtimeServiceEnabled18ED891C": Object { + "Fn::Not": Array [ + Object { + "Fn::Equals": Array [ + Object { + "Ref": "RealtimeTaskSize6077FE1F", + }, + "none", + ], + }, + ], + }, + "RestAutoScalingEnabled69452861": Object { + "Fn::And": Array [ + Object { + "Condition": "RestServiceEnabledD6F99FCE", + }, + Object { + "Condition": "HighAvailability", + }, + ], + }, + "RestServiceEnabledD6F99FCE": Object { + "Fn::Not": Array [ + Object { + "Fn::Equals": Array [ + Object { + "Ref": "RestTaskSize14E11A14", + }, + "none", + ], + }, + ], + }, + "StorageAutoScalingEnabled4D34646B": Object { + "Fn::And": Array [ + Object { + "Condition": "StorageServiceEnabled58819374", + }, + Object { + "Condition": "HighAvailability", + }, + ], + }, + "StorageServiceEnabled58819374": Object { + "Fn::Not": Array [ + Object { + "Fn::Equals": Array [ + Object { + "Ref": "StorageTaskSizeB82D9CFB", + }, + "none", + ], }, - "0", ], }, "WorkMailEnabled": Object { @@ -353,6 +465,10 @@ Object { "cpu": 256, "memory": 1024, }, + "none": Object { + "cpu": 256, + "memory": 1024, + }, "small": Object { "cpu": 512, "memory": 1024, @@ -380,7 +496,7 @@ Object { }, Object { "Label": Object { - "default": "Supabase - Auth E-mail Settings", + "default": "Supabase - SMTP Settings", }, "Parameters": Array [ "Email", @@ -391,7 +507,7 @@ Object { }, Object { "Label": Object { - "default": "Supabase - Container Image URIs", + "default": "Supabase - Versions (Container Images)", }, "Parameters": Array [ "AuthImageUri", @@ -405,99 +521,35 @@ Object { }, Object { "Label": Object { - "default": "Infrastructure Settings - Database", - }, - "Parameters": Array [ - "MinACU", - "MaxACU", - ], - }, - Object { - "Label": Object { - "default": "Infrastructure Settings - Security", + "default": "Infrastructure Settings", }, "Parameters": Array [ + "EnableHighAvailability", "CdnWebAclArn5923748A", ], }, Object { "Label": Object { - "default": "Infrastructure Settings - Kong (API Gateway)", + "default": "Infrastructure Settings - Database", }, "Parameters": Array [ - "KongTaskSize93C195E9", - "KongMinTaskCount4451EF4C", - "KongMaxTaskCountA4145D65", + "MinACU", + "MaxACU", ], }, Object { "Label": Object { - "default": "Infrastructure Settings - Auth API (GoTrue)", + "default": "Infrastructure Settings - Containers", }, "Parameters": Array [ + "KongTaskSize93C195E9", "AuthTaskSize9895C206", - "AuthMinTaskCount998F20C4", - "AuthMaxTaskCount9E585BDA", - ], - }, - Object { - "Label": Object { - "default": "Infrastructure Settings - RESTful API (PostgREST)", - }, - "Parameters": Array [ "RestTaskSize14E11A14", - "RestMinTaskCount073959EA", - "RestMaxTaskCount1D2E84B9", - ], - }, - Object { - "Label": Object { - "default": "Infrastructure Settings - GraphQL API (PostGraphile)", - }, - "Parameters": Array [ "GraphQLTaskSize228AD0D2", - "GraphQLMinTaskCount0807D92D", - "GraphQLMaxTaskCount62412A02", - ], - }, - Object { - "Label": Object { - "default": "Infrastructure Settings - Realtime API", - }, - "Parameters": Array [ "RealtimeTaskSize6077FE1F", - "RealtimeMinTaskCount306F67E8", - "RealtimeMaxTaskCountE72E1120", - ], - }, - Object { - "Label": Object { - "default": "Infrastructure Settings - Storage API", - }, - "Parameters": Array [ "StorageTaskSizeB82D9CFB", - "StorageMinTaskCount07E65703", - "StorageMaxTaskCount372C6914", - ], - }, - Object { - "Label": Object { - "default": "Infrastructure Settings - Imgproxy", - }, - "Parameters": Array [ "ImgproxyTaskSize5D0DD9F6", - "ImgproxyMinTaskCount7B881431", - "ImgproxyMaxTaskCount4DF8AF60", - ], - }, - Object { - "Label": Object { - "default": "Infrastructure Settings - Postgres Meta API", - }, - "Parameters": Array [ "MetaTaskSize556D36D9", - "MetaMinTaskCountEA12F444", - "MetaMaxTaskCount2749DE86", ], }, Object { @@ -533,13 +585,7 @@ Object { ], "ParameterLabels": Object { "AuthImageUri": Object { - "default": "Auth API Image URI - GoTrue", - }, - "AuthMaxTaskCount9E585BDA": Object { - "default": "Maximum Fargate Task Count", - }, - "AuthMinTaskCount998F20C4": Object { - "default": "Minimum Fargate Task Count", + "default": "Image URI - GoTrue", }, "AuthProvider1ClientId5614D178": Object { "default": "Client ID", @@ -569,7 +615,7 @@ Object { "default": "Client Secret", }, "AuthTaskSize9895C206": Object { - "default": "Fargate Task Size", + "default": "Task Size - GoTrue", }, "CdnWebAclArn5923748A": Object { "default": "Web ACL ARN (AWS WAF)", @@ -580,53 +626,32 @@ Object { "Email": Object { "default": "Sender Email Address", }, + "EnableHighAvailability": Object { + "default": "High Availability (HA)", + }, "EnableWorkMail": Object { "default": "Enable Test E-mail Domain (via Amazon WorkMail)", }, - "GraphQLMaxTaskCount62412A02": Object { - "default": "Maximum Fargate Task Count", - }, - "GraphQLMinTaskCount0807D92D": Object { - "default": "Minimum Fargate Task Count", - }, "GraphQLTaskSize228AD0D2": Object { - "default": "Fargate Task Size", + "default": "Task Size - PostGraphile", }, "ImgproxyImageUri": Object { - "default": "Imgproxy Image URI", - }, - "ImgproxyMaxTaskCount4DF8AF60": Object { - "default": "Maximum Fargate Task Count", - }, - "ImgproxyMinTaskCount7B881431": Object { - "default": "Minimum Fargate Task Count", + "default": "Image URI - imgproxy", }, "ImgproxyTaskSize5D0DD9F6": Object { - "default": "Fargate Task Size", + "default": "Task Size - imgproxy", }, "JwtExpiryLimit": Object { "default": "JWT expiry limit", }, - "KongMaxTaskCountA4145D65": Object { - "default": "Maximum Fargate Task Count", - }, - "KongMinTaskCount4451EF4C": Object { - "default": "Minimum Fargate Task Count", - }, "KongTaskSize93C195E9": Object { - "default": "Fargate Task Size", + "default": "Task Size - Kong", }, "MaxACU": Object { "default": "Maximum ACUs", }, - "MetaMaxTaskCount2749DE86": Object { - "default": "Maximum Fargate Task Count", - }, - "MetaMinTaskCountEA12F444": Object { - "default": "Minimum Fargate Task Count", - }, "MetaTaskSize556D36D9": Object { - "default": "Fargate Task Size", + "default": "Task Size - postgres-meta", }, "MinACU": Object { "default": "Minimum ACUs", @@ -635,34 +660,22 @@ Object { "default": "Min password length", }, "PostgresMetaImageUri": Object { - "default": "Postgres Meta API Image URI", + "default": "Image URI - postgres-meta", }, "RealtimeImageUri": Object { - "default": "Realtime API Image URI", - }, - "RealtimeMaxTaskCountE72E1120": Object { - "default": "Maximum Fargate Task Count", - }, - "RealtimeMinTaskCount306F67E8": Object { - "default": "Minimum Fargate Task Count", + "default": "Image URI - Realtime", }, "RealtimeTaskSize6077FE1F": Object { - "default": "Fargate Task Size", + "default": "Task Size - Realtime", }, "RedirectUrls": Object { "default": "Redirect URLs", }, "RestImageUri": Object { - "default": "Rest API Image URI - PostgREST", - }, - "RestMaxTaskCount1D2E84B9": Object { - "default": "Maximum Fargate Task Count", - }, - "RestMinTaskCount073959EA": Object { - "default": "Minimum Fargate Task Count", + "default": "Image URI - PostgREST", }, "RestTaskSize14E11A14": Object { - "default": "Fargate Task Size", + "default": "Task Size - PostgREST", }, "SenderName": Object { "default": "Sender Name", @@ -674,16 +687,10 @@ Object { "default": "Site URL", }, "StorageImageUri": Object { - "default": "Storage API Image URI", - }, - "StorageMaxTaskCount372C6914": Object { - "default": "Maximum Fargate Task Count", - }, - "StorageMinTaskCount07E65703": Object { - "default": "Minimum Fargate Task Count", + "default": "Image URI - Storage", }, "StorageTaskSizeB82D9CFB": Object { - "default": "Fargate Task Size", + "default": "Task Size - Storage", }, "StudioBranch": Object { "default": "Supabase Studio Branch", @@ -774,18 +781,6 @@ Object { "Description": "https://gallery.ecr.aws/supabase/gotrue", "Type": "String", }, - "AuthMaxTaskCount9E585BDA": Object { - "Default": 20, - "Description": "Maximum fargate task count", - "MinValue": 0, - "Type": "Number", - }, - "AuthMinTaskCount998F20C4": Object { - "Default": 1, - "Description": "Minimum fargate task count", - "MinValue": 0, - "Type": "Number", - }, "AuthProvider1ClientId5614D178": Object { "Default": "", "Description": "The OAuth2 Client ID registered with the external provider.", @@ -893,6 +888,7 @@ Object { }, "AuthTaskSize9895C206": Object { "AllowedValues": Array [ + "none", "micro", "small", "medium", @@ -901,7 +897,7 @@ Object { "2xlarge", "4xlarge", ], - "Default": "micro", + "Default": "medium", "Description": "Fargare task size", "Type": "String", }, @@ -950,20 +946,9 @@ Object { "Description": "Enable test e-mail domain \\"xxx.awsapps.com\\" with Amazon WorkMail.", "Type": "String", }, - "GraphQLMaxTaskCount62412A02": Object { - "Default": 20, - "Description": "Maximum fargate task count", - "MinValue": 0, - "Type": "Number", - }, - "GraphQLMinTaskCount0807D92D": Object { - "Default": 1, - "Description": "Minimum fargate task count", - "MinValue": 0, - "Type": "Number", - }, "GraphQLTaskSize228AD0D2": Object { "AllowedValues": Array [ + "none", "micro", "small", "medium", @@ -972,7 +957,7 @@ Object { "2xlarge", "4xlarge", ], - "Default": "micro", + "Default": "medium", "Description": "Fargare task size", "Type": "String", }, @@ -981,20 +966,9 @@ Object { "Description": "https://gallery.ecr.aws/supabase/imgproxy", "Type": "String", }, - "ImgproxyMaxTaskCount4DF8AF60": Object { - "Default": 20, - "Description": "Maximum fargate task count", - "MinValue": 0, - "Type": "Number", - }, - "ImgproxyMinTaskCount7B881431": Object { - "Default": 1, - "Description": "Minimum fargate task count", - "MinValue": 0, - "Type": "Number", - }, "ImgproxyTaskSize5D0DD9F6": Object { "AllowedValues": Array [ + "none", "micro", "small", "medium", @@ -1003,7 +977,7 @@ Object { "2xlarge", "4xlarge", ], - "Default": "micro", + "Default": "medium", "Description": "Fargare task size", "Type": "String", }, @@ -1014,20 +988,9 @@ Object { "MinValue": 300, "Type": "Number", }, - "KongMaxTaskCountA4145D65": Object { - "Default": 20, - "Description": "Maximum fargate task count", - "MinValue": 0, - "Type": "Number", - }, - "KongMinTaskCount4451EF4C": Object { - "Default": 1, - "Description": "Minimum fargate task count", - "MinValue": 0, - "Type": "Number", - }, "KongTaskSize93C195E9": Object { "AllowedValues": Array [ + "none", "micro", "small", "medium", @@ -1036,7 +999,7 @@ Object { "2xlarge", "4xlarge", ], - "Default": "micro", + "Default": "medium", "Description": "Fargare task size", "Type": "String", }, @@ -1047,20 +1010,9 @@ Object { "MinValue": 0.5, "Type": "Number", }, - "MetaMaxTaskCount2749DE86": Object { - "Default": 20, - "Description": "Maximum fargate task count", - "MinValue": 0, - "Type": "Number", - }, - "MetaMinTaskCountEA12F444": Object { - "Default": 1, - "Description": "Minimum fargate task count", - "MinValue": 0, - "Type": "Number", - }, "MetaTaskSize556D36D9": Object { "AllowedValues": Array [ + "none", "micro", "small", "medium", @@ -1069,7 +1021,7 @@ Object { "2xlarge", "4xlarge", ], - "Default": "micro", + "Default": "medium", "Description": "Fargare task size", "Type": "String", }, @@ -1097,20 +1049,9 @@ Object { "Description": "https://gallery.ecr.aws/supabase/realtime", "Type": "String", }, - "RealtimeMaxTaskCountE72E1120": Object { - "Default": 20, - "Description": "Maximum fargate task count", - "MinValue": 0, - "Type": "Number", - }, - "RealtimeMinTaskCount306F67E8": Object { - "Default": 1, - "Description": "Minimum fargate task count", - "MinValue": 0, - "Type": "Number", - }, "RealtimeTaskSize6077FE1F": Object { "AllowedValues": Array [ + "none", "micro", "small", "medium", @@ -1119,7 +1060,7 @@ Object { "2xlarge", "4xlarge", ], - "Default": "micro", + "Default": "medium", "Description": "Fargare task size", "Type": "String", }, @@ -1133,20 +1074,9 @@ Object { "Description": "https://gallery.ecr.aws/supabase/postgrest", "Type": "String", }, - "RestMaxTaskCount1D2E84B9": Object { - "Default": 20, - "Description": "Maximum fargate task count", - "MinValue": 0, - "Type": "Number", - }, - "RestMinTaskCount073959EA": Object { - "Default": 1, - "Description": "Minimum fargate task count", - "MinValue": 0, - "Type": "Number", - }, "RestTaskSize14E11A14": Object { "AllowedValues": Array [ + "none", "micro", "small", "medium", @@ -1155,7 +1085,7 @@ Object { "2xlarge", "4xlarge", ], - "Default": "micro", + "Default": "medium", "Description": "Fargare task size", "Type": "String", }, @@ -1198,20 +1128,9 @@ Object { "Description": "https://gallery.ecr.aws/supabase/storage-api", "Type": "String", }, - "StorageMaxTaskCount372C6914": Object { - "Default": 20, - "Description": "Maximum fargate task count", - "MinValue": 0, - "Type": "Number", - }, - "StorageMinTaskCount07E65703": Object { - "Default": 1, - "Description": "Minimum fargate task count", - "MinValue": 0, - "Type": "Number", - }, "StorageTaskSizeB82D9CFB": Object { "AllowedValues": Array [ + "none", "micro", "small", "medium", @@ -1220,7 +1139,7 @@ Object { "2xlarge", "4xlarge", ], - "Default": "micro", + "Default": "medium", "Description": "Fargare task size", "Type": "String", }, @@ -1609,11 +1528,11 @@ Object { }, "DesiredCount": Object { "Fn::If": Array [ - "AuthServiceDisabledB6209B31", - 0, + "AuthServiceEnabled3234D87F", Object { "Ref": "AWS::NoValue", }, + 0, ], }, "EnableECSManagedTags": true, @@ -1757,13 +1676,10 @@ Object { "Type": "AWS::EC2::SecurityGroupIngress", }, "AuthServiceTaskCountTarget07A8CCD2": Object { + "Condition": "AuthAutoScalingEnabled0CD7354E", "Properties": Object { - "MaxCapacity": Object { - "Ref": "AuthMaxTaskCount9E585BDA", - }, - "MinCapacity": Object { - "Ref": "AuthMinTaskCount998F20C4", - }, + "MaxCapacity": 20, + "MinCapacity": 2, "ResourceId": Object { "Fn::Join": Array [ "", @@ -1804,6 +1720,7 @@ Object { "Type": "AWS::ApplicationAutoScaling::ScalableTarget", }, "AuthServiceTaskCountTargetScaleOnCpu0847ACEC": Object { + "Condition": "AuthAutoScalingEnabled0CD7354E", "Properties": Object { "PolicyName": "SupabaseAuthServiceTaskCountTargetScaleOnCpu253117F9", "PolicyType": "TargetTrackingScaling", @@ -4832,11 +4749,11 @@ Object { }, "DesiredCount": Object { "Fn::If": Array [ - "GraphQLServiceDisabled2040BDFB", - 0, + "GraphQLServiceEnabledC2BD6E3B", Object { "Ref": "AWS::NoValue", }, + 0, ], }, "EnableECSManagedTags": true, @@ -4980,13 +4897,10 @@ Object { "Type": "AWS::EC2::SecurityGroupIngress", }, "GraphQLServiceTaskCountTargetD74EBB91": Object { + "Condition": "GraphQLAutoScalingEnabled686BA277", "Properties": Object { - "MaxCapacity": Object { - "Ref": "GraphQLMaxTaskCount62412A02", - }, - "MinCapacity": Object { - "Ref": "GraphQLMinTaskCount0807D92D", - }, + "MaxCapacity": 20, + "MinCapacity": 2, "ResourceId": Object { "Fn::Join": Array [ "", @@ -5027,6 +4941,7 @@ Object { "Type": "AWS::ApplicationAutoScaling::ScalableTarget", }, "GraphQLServiceTaskCountTargetScaleOnCpu65C9F8E9": Object { + "Condition": "GraphQLAutoScalingEnabled686BA277", "Properties": Object { "PolicyName": "SupabaseGraphQLServiceTaskCountTargetScaleOnCpuE8FC1CFC", "PolicyType": "TargetTrackingScaling", @@ -5279,11 +5194,11 @@ Object { }, "DesiredCount": Object { "Fn::If": Array [ - "ImgproxyServiceDisabledE6934A15", - 0, + "ImgproxyServiceEnabled64E773FC", Object { "Ref": "AWS::NoValue", }, + 0, ], }, "EnableECSManagedTags": true, @@ -5427,13 +5342,10 @@ Object { "Type": "AWS::EC2::SecurityGroupIngress", }, "ImgproxyServiceTaskCountTargetC19355BF": Object { + "Condition": "ImgproxyAutoScalingEnabled44E9E87F", "Properties": Object { - "MaxCapacity": Object { - "Ref": "ImgproxyMaxTaskCount4DF8AF60", - }, - "MinCapacity": Object { - "Ref": "ImgproxyMinTaskCount7B881431", - }, + "MaxCapacity": 20, + "MinCapacity": 2, "ResourceId": Object { "Fn::Join": Array [ "", @@ -5474,6 +5386,7 @@ Object { "Type": "AWS::ApplicationAutoScaling::ScalableTarget", }, "ImgproxyServiceTaskCountTargetScaleOnCpuADE19FC6": Object { + "Condition": "ImgproxyAutoScalingEnabled44E9E87F", "Properties": Object { "PolicyName": "SupabaseImgproxyServiceTaskCountTargetScaleOnCpu2F1B6C7E", "PolicyType": "TargetTrackingScaling", @@ -6025,11 +5938,11 @@ Object { }, "DesiredCount": Object { "Fn::If": Array [ - "KongServiceDisabled5CB631B8", - 0, + "KongServiceEnabled5CB62A18", Object { "Ref": "AWS::NoValue", }, + 0, ], }, "EnableECSManagedTags": true, @@ -6204,13 +6117,10 @@ Object { "Type": "AWS::EC2::SecurityGroupIngress", }, "KongServiceTaskCountTarget5CD21EEB": Object { + "Condition": "KongAutoScalingEnabled41DC2F80", "Properties": Object { - "MaxCapacity": Object { - "Ref": "KongMaxTaskCountA4145D65", - }, - "MinCapacity": Object { - "Ref": "KongMinTaskCount4451EF4C", - }, + "MaxCapacity": 20, + "MinCapacity": 2, "ResourceId": Object { "Fn::Join": Array [ "", @@ -6251,6 +6161,7 @@ Object { "Type": "AWS::ApplicationAutoScaling::ScalableTarget", }, "KongServiceTaskCountTargetScaleOnCpuE9FBE5E2": Object { + "Condition": "KongAutoScalingEnabled41DC2F80", "Properties": Object { "PolicyName": "SupabaseKongServiceTaskCountTargetScaleOnCpu7C47F3C3", "PolicyType": "TargetTrackingScaling", @@ -6753,11 +6664,11 @@ Object { }, "DesiredCount": Object { "Fn::If": Array [ - "MetaServiceDisabled3B808F33", - 0, + "MetaServiceEnabled094DCF06", Object { "Ref": "AWS::NoValue", }, + 0, ], }, "EnableECSManagedTags": true, @@ -6910,16 +6821,13 @@ Object { "Type": "AWS::EC2::SecurityGroupIngress", }, "MetaServiceTaskCountTarget124C5BFA": Object { + "Condition": "MetaAutoScalingEnabledCF28EDB1", "DependsOn": Array [ "DatabaseMigration993F5B9C", ], "Properties": Object { - "MaxCapacity": Object { - "Ref": "MetaMaxTaskCount2749DE86", - }, - "MinCapacity": Object { - "Ref": "MetaMinTaskCountEA12F444", - }, + "MaxCapacity": 20, + "MinCapacity": 2, "ResourceId": Object { "Fn::Join": Array [ "", @@ -6960,6 +6868,7 @@ Object { "Type": "AWS::ApplicationAutoScaling::ScalableTarget", }, "MetaServiceTaskCountTargetScaleOnCpuBFDCF132": Object { + "Condition": "MetaAutoScalingEnabledCF28EDB1", "DependsOn": Array [ "DatabaseMigration993F5B9C", ], @@ -7229,11 +7138,11 @@ Object { }, "DesiredCount": Object { "Fn::If": Array [ - "RealtimeServiceDisabledD3DB8A99", - 0, + "RealtimeServiceEnabled18ED891C", Object { "Ref": "AWS::NoValue", }, + 0, ], }, "EnableECSManagedTags": true, @@ -7408,16 +7317,13 @@ Object { "Type": "AWS::EC2::SecurityGroupIngress", }, "RealtimeServiceTaskCountTarget89349CD4": Object { + "Condition": "RealtimeAutoScalingEnabled7991ED3B", "DependsOn": Array [ "DatabaseMigration993F5B9C", ], "Properties": Object { - "MaxCapacity": Object { - "Ref": "RealtimeMaxTaskCountE72E1120", - }, - "MinCapacity": Object { - "Ref": "RealtimeMinTaskCount306F67E8", - }, + "MaxCapacity": 20, + "MinCapacity": 2, "ResourceId": Object { "Fn::Join": Array [ "", @@ -7458,6 +7364,7 @@ Object { "Type": "AWS::ApplicationAutoScaling::ScalableTarget", }, "RealtimeServiceTaskCountTargetScaleOnCpu764115FF": Object { + "Condition": "RealtimeAutoScalingEnabled7991ED3B", "DependsOn": Array [ "DatabaseMigration993F5B9C", ], @@ -7795,11 +7702,11 @@ Object { }, "DesiredCount": Object { "Fn::If": Array [ - "RestServiceDisabled280508EE", - 0, + "RestServiceEnabledD6F99FCE", Object { "Ref": "AWS::NoValue", }, + 0, ], }, "EnableECSManagedTags": true, @@ -7985,13 +7892,10 @@ Object { "Type": "AWS::EC2::SecurityGroupIngress", }, "RestServiceTaskCountTarget8C6E8E1E": Object { + "Condition": "RestAutoScalingEnabled69452861", "Properties": Object { - "MaxCapacity": Object { - "Ref": "RestMaxTaskCount1D2E84B9", - }, - "MinCapacity": Object { - "Ref": "RestMinTaskCount073959EA", - }, + "MaxCapacity": 20, + "MinCapacity": 2, "ResourceId": Object { "Fn::Join": Array [ "", @@ -8032,6 +7936,7 @@ Object { "Type": "AWS::ApplicationAutoScaling::ScalableTarget", }, "RestServiceTaskCountTargetScaleOnCpuE9845870": Object { + "Condition": "RestAutoScalingEnabled69452861", "Properties": Object { "PolicyName": "SupabaseRestServiceTaskCountTargetScaleOnCpuB529B263", "PolicyType": "TargetTrackingScaling", @@ -8612,11 +8517,11 @@ Object { }, "DesiredCount": Object { "Fn::If": Array [ - "StorageServiceDisabled05C15E2C", - 0, + "StorageServiceEnabled58819374", Object { "Ref": "AWS::NoValue", }, + 0, ], }, "EnableECSManagedTags": true, @@ -8760,13 +8665,10 @@ Object { "Type": "AWS::EC2::SecurityGroupIngress", }, "StorageServiceTaskCountTargetAF72160A": Object { + "Condition": "StorageAutoScalingEnabled4D34646B", "Properties": Object { - "MaxCapacity": Object { - "Ref": "StorageMaxTaskCount372C6914", - }, - "MinCapacity": Object { - "Ref": "StorageMinTaskCount07E65703", - }, + "MaxCapacity": 20, + "MinCapacity": 2, "ResourceId": Object { "Fn::Join": Array [ "", @@ -8807,6 +8709,7 @@ Object { "Type": "AWS::ApplicationAutoScaling::ScalableTarget", }, "StorageServiceTaskCountTargetScaleOnCpuDB3B903C": Object { + "Condition": "StorageAutoScalingEnabled4D34646B", "Properties": Object { "PolicyName": "SupabaseStorageServiceTaskCountTargetScaleOnCpuE2C72C87", "PolicyType": "TargetTrackingScaling", From e60780d4fa9b666ab81f537dfc1206675be56dec Mon Sep 17 00:00:00 2001 From: Kazuki Matsuda Date: Sun, 2 Jul 2023 22:28:20 +0900 Subject: [PATCH 3/3] refactorimg --- src/supabase-cdn/index.ts | 21 ++----- src/supabase-stack.ts | 17 +++++- test/__snapshots__/main.test.ts.snap | 88 ++++++++++++++-------------- 3 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/supabase-cdn/index.ts b/src/supabase-cdn/index.ts index 506c6c8..d36fc8d 100644 --- a/src/supabase-cdn/index.ts +++ b/src/supabase-cdn/index.ts @@ -16,6 +16,7 @@ import { WebAcl } from '../aws-waf'; interface SupabaseCdnProps { origin: string|elb.ILoadBalancerV2; + webAclArn: cdk.CfnParameter; } interface BehaviorProps { @@ -26,9 +27,6 @@ interface BehaviorProps { export class SupabaseCdn extends Construct { distribution: cf.Distribution; defaultBehaviorOptions: cf.AddBehaviorOptions; - cfnParameters: { - webAclArn: cdk.CfnParameter; - }; /** Construct for CloudFront and WAF */ constructor(scope: Construct, id: string, props: SupabaseCdnProps) { @@ -39,23 +37,14 @@ export class SupabaseCdn extends Construct { ? new HttpOrigin(props.origin, { protocolPolicy: cf.OriginProtocolPolicy.HTTPS_ONLY }) : new LoadBalancerV2Origin(props.origin, { protocolPolicy: cf.OriginProtocolPolicy.HTTP_ONLY }); - this.cfnParameters = { - webAclArn: new cdk.CfnParameter(this, 'WebAclArn', { - description: 'Web ACL for CloudFront.', - type: 'String', - default: '', - allowedPattern: '^arn:aws:wafv2:us-east-1:[0-9]{12}:global/webacl/[\\w-]+/[\\w]{8}-[\\w]{4}-[\\w]{4}-[\\w]{4}-[\\w]{12}$|', - }), - }; - - const webAclUndefined = new cdk.CfnCondition(this, 'WebAclUndefined', { expression: cdk.Fn.conditionEquals(this.cfnParameters.webAclArn, '') }); + const defaultWebAclEnabled = new cdk.CfnCondition(this, 'DefaultWebAclEnabled', { expression: cdk.Fn.conditionEquals(props.webAclArn, '') }); /** Default Web ACL */ - const webAcl = new WebAcl(this, 'WebAcl', { description: 'Supabase Standard WebAcl' }); - (webAcl.node.defaultChild as cdk.CfnStack).cfnOptions.condition = webAclUndefined; + const defaultWebAcl = new WebAcl(this, 'DefaultWebAcl', { description: 'Default Web ACL' }); + (defaultWebAcl.node.defaultChild as cdk.CfnStack).cfnOptions.condition = defaultWebAclEnabled; /** Web ACL ID */ - const webAclId = cdk.Fn.conditionIf(webAclUndefined.logicalId, webAcl.webAclArn, this.cfnParameters.webAclArn.valueAsString); + const webAclId = cdk.Fn.conditionIf(defaultWebAclEnabled.logicalId, defaultWebAcl.webAclArn, props.webAclArn.valueAsString); const cachePolicy = new cf.CachePolicy(this, 'CachePolicy', { cachePolicyName: `${cdk.Aws.STACK_NAME}-CachePolicy-${cdk.Aws.REGION}`, diff --git a/src/supabase-stack.ts b/src/supabase-stack.ts index 583cb80..ad251e7 100644 --- a/src/supabase-stack.ts +++ b/src/supabase-stack.ts @@ -135,6 +135,14 @@ export class SupabaseStack extends FargateStack { /** CFn condition for High Availability */ const highAvailability = new cdk.CfnCondition(this, 'HighAvailability', { expression: cdk.Fn.conditionEquals(enableHighAvailability, 'true') }); + /** Web ACL for CloudFront */ + const webAclArn = new cdk.CfnParameter(this, 'WebAclArn', { + description: 'Web ACL for CloudFront.', + type: 'String', + default: '', + allowedPattern: '^arn:aws:wafv2:us-east-1:[0-9]{12}:global/webacl/[\\w-]+/[\\w]{8}-[\\w]{4}-[\\w]{4}-[\\w]{4}-[\\w]{12}$|', + }); + /** The minimum number of aurora capacity units */ const minACU = new cdk.CfnParameter(this, 'MinACU', { description: 'The minimum number of Aurora capacity units (ACU) for a DB instance in an Aurora Serverless v2 cluster.', @@ -258,7 +266,10 @@ export class SupabaseStack extends FargateStack { loadBalancer.connections.allowFrom(Peer.prefixList(cfPrefixList.prefixListId), Port.tcp(80), 'CloudFront'); /** CloudFront */ - const cdn = new SupabaseCdn(this, 'Cdn', { origin: loadBalancer }); + const cdn = new SupabaseCdn(this, 'Cdn', { + origin: loadBalancer, + webAclArn, + }); /** * Supabase API URL @@ -695,7 +706,7 @@ export class SupabaseStack extends FargateStack { Label: { default: 'Infrastructure Settings' }, Parameters: [ enableHighAvailability.logicalId, - cdn.cfnParameters.webAclArn.logicalId, + webAclArn.logicalId, ], }, { @@ -738,7 +749,7 @@ export class SupabaseStack extends FargateStack { [postgresMetaImageUri.logicalId]: { default: 'Image URI - postgres-meta' }, [enableHighAvailability.logicalId]: { default: 'High Availability (HA)' }, - [cdn.cfnParameters.webAclArn.logicalId]: { default: 'Web ACL ARN (AWS WAF)' }, + [webAclArn.logicalId]: { default: 'Web ACL ARN (AWS WAF)' }, [minACU.logicalId]: { default: 'Minimum ACUs' }, [maxACU.logicalId]: { default: 'Maximum ACUs' }, diff --git a/test/__snapshots__/main.test.ts.snap b/test/__snapshots__/main.test.ts.snap index 1e85117..a10c476 100644 --- a/test/__snapshots__/main.test.ts.snap +++ b/test/__snapshots__/main.test.ts.snap @@ -61,10 +61,10 @@ Object { }, ], }, - "CdnWebAclUndefinedCAA325A4": Object { + "CdnDefaultWebAclEnabled46EA1324": Object { "Fn::Equals": Array [ Object { - "Ref": "CdnWebAclArn5923748A", + "Ref": "WebAclArn", }, "", ], @@ -525,7 +525,7 @@ Object { }, "Parameters": Array [ "EnableHighAvailability", - "CdnWebAclArn5923748A", + "WebAclArn", ], }, Object { @@ -617,9 +617,6 @@ Object { "AuthTaskSize9895C206": Object { "default": "Task Size - GoTrue", }, - "CdnWebAclArn5923748A": Object { - "default": "Web ACL ARN (AWS WAF)", - }, "DisableSignup": Object { "default": "Disable User Signups", }, @@ -695,6 +692,9 @@ Object { "StudioBranch": Object { "default": "Supabase Studio Branch", }, + "WebAclArn": Object { + "default": "Web ACL ARN (AWS WAF)", + }, }, }, }, @@ -906,12 +906,6 @@ Object { "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]", "Type": "AWS::SSM::Parameter::Value", }, - "CdnWebAclArn5923748A": Object { - "AllowedPattern": "^arn:aws:wafv2:us-east-1:[0-9]{12}:global/webacl/[\\\\w-]+/[\\\\w]{8}-[\\\\w]{4}-[\\\\w]{4}-[\\\\w]{4}-[\\\\w]{12}$|", - "Default": "", - "Description": "Web ACL for CloudFront.", - "Type": "String", - }, "DisableSignup": Object { "AllowedValues": Array [ "true", @@ -1148,6 +1142,12 @@ Object { "Description": "Branch or tag - https://github.com/supabase/supabase/tags", "Type": "String", }, + "WebAclArn": Object { + "AllowedPattern": "^arn:aws:wafv2:us-east-1:[0-9]{12}:global/webacl/[\\\\w-]+/[\\\\w]{8}-[\\\\w]{4}-[\\\\w]{4}-[\\\\w]{4}-[\\\\w]{12}$|", + "Default": "", + "Description": "Web ACL for CloudFront.", + "Type": "String", + }, }, "Resources": Object { "AWS679f53fac002430cb0da5b7982bd22872D164C4C": Object { @@ -3158,6 +3158,34 @@ Object { }, "Type": "AWS::CloudFront::CachePolicy", }, + "CdnDefaultWebAclNestedStackDefaultWebAclNestedStackResource663284CA": Object { + "Condition": "CdnDefaultWebAclEnabled46EA1324", + "DeletionPolicy": "Delete", + "Properties": Object { + "TemplateURL": Object { + "Fn::Join": Array [ + "", + Array [ + "https://s3.", + Object { + "Ref": "AWS::Region", + }, + ".", + Object { + "Ref": "AWS::URLSuffix", + }, + "/", + Object { + "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}", + }, + "/e80cb6c3c32610200a4d46711e67c7e759a066534a83f2cc6d493c51fceecfd4.json", + ], + ], + }, + }, + "Type": "AWS::CloudFormation::Stack", + "UpdateReplacePolicy": "Delete", + }, "CdnDistribution149FA6C8": Object { "Properties": Object { "DistributionConfig": Object { @@ -3244,15 +3272,15 @@ Object { ], "WebACLId": Object { "Fn::If": Array [ - "CdnWebAclUndefinedCAA325A4", + "CdnDefaultWebAclEnabled46EA1324", Object { "Fn::GetAtt": Array [ - "CdnWebAclNestedStackWebAclNestedStackResourceFDB876C0", - "Outputs.SupabaseCdnWebAcl5ECF61CDArn", + "CdnDefaultWebAclNestedStackDefaultWebAclNestedStackResource663284CA", + "Outputs.SupabaseCdnDefaultWebAcl261D81EEArn", ], }, Object { - "Ref": "CdnWebAclArn5923748A", + "Ref": "WebAclArn", }, ], }, @@ -3291,34 +3319,6 @@ Object { }, "Type": "AWS::CloudFront::ResponseHeadersPolicy", }, - "CdnWebAclNestedStackWebAclNestedStackResourceFDB876C0": Object { - "Condition": "CdnWebAclUndefinedCAA325A4", - "DeletionPolicy": "Delete", - "Properties": Object { - "TemplateURL": Object { - "Fn::Join": Array [ - "", - Array [ - "https://s3.", - Object { - "Ref": "AWS::Region", - }, - ".", - Object { - "Ref": "AWS::URLSuffix", - }, - "/", - Object { - "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}", - }, - "/ba9bddc91e6877cd649a7a9325179bbfbdd2c97b72a2f25a9f36c87e52b48ab4.json", - ], - ], - }, - }, - "Type": "AWS::CloudFormation::Stack", - "UpdateReplacePolicy": "Delete", - }, "CloudFrontPrefixList22014EFD": Object { "DeletionPolicy": "Delete", "DependsOn": Array [