Skip to content

Commit

Permalink
Merge pull request #54 from supabase-community/refactor-cfn-parameter
Browse files Browse the repository at this point in the history
feat: fix static credentials for Studio
  • Loading branch information
mats16 authored Jul 4, 2023
2 parents db7c8dd + ad14dc8 commit 97c37f7
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 73 deletions.
22 changes: 8 additions & 14 deletions src/supabase-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import * as s3 from 'aws-cdk-lib/aws-s3';
import { Secret } from 'aws-cdk-lib/aws-secretsmanager';
import { Construct } from 'constructs';
import { SesSmtp } from './amazon-ses-smtp';
import { AmplifyHosting } from './aws-amplify-hosting';
import { PrefixList } from './aws-prefix-list';
import { ForceDeployJob } from './ecs-force-deploy-job';
import { AutoScalingFargateService } from './ecs-patterns';
import { JwtSecret } from './json-web-token';
import { SupabaseCdn } from './supabase-cdn';
import { SupabaseDatabase } from './supabase-db';
import { SupabaseStudio } from './supabase-studio';

export class FargateStack extends cdk.Stack {
/** ECS Fargate task size mappings */
Expand Down Expand Up @@ -232,6 +232,8 @@ export class SupabaseStack extends FargateStack {
const supabaseStorageAdminSecret = db.genUserPassword('supabase_storage_admin');
/** Secret of authenticator user */
const authenticatorSecret = db.genUserPassword('authenticator');
/** Secret of dashboard user */
const dashboardUserSecret = db.genUserPassword('dashboard_user');
/** Secret of postgres user */
const postgresSecret = db.genUserPassword('postgres');

Expand Down Expand Up @@ -638,20 +640,12 @@ export class SupabaseStack extends FargateStack {
});

/** Supabase Studio */
const studio = new AmplifyHosting(this, 'Studio', {
sourceRepo: 'https://github.com/supabase/supabase.git',
const studio = new SupabaseStudio(this, 'Studio', {
sourceBranch: studioBranch.valueAsString,
appRoot: 'studio',
environment: {
STUDIO_PG_META_URL: `${apiExternalUrl}/pg`,
POSTGRES_PASSWORD: supabaseAdminSecret.secretValueFromJson('password').toString(),
//DEFAULT_ORGANIZATION: 'Default Organization',
//DEFAULT_PROJECT: 'Default Project',
SUPABASE_URL: `${apiExternalUrl}`,
SUPABASE_PUBLIC_URL: `${apiExternalUrl}`,
SUPABASE_ANON_KEY: anonKey.value,
SUPABASE_SERVICE_KEY: serviceRoleKey.value,
},
supabaseUrl: apiExternalUrl,
dbSecret: dashboardUserSecret,
anonKey: anonKey.ssmParameter,
serviceRoleKey: serviceRoleKey.ssmParameter,
});

new cdk.CfnOutput(this, 'SupabaseUrl', {
Expand Down
65 changes: 42 additions & 23 deletions src/aws-amplify-hosting.ts → src/supabase-studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,37 @@ import { BuildSpec } from 'aws-cdk-lib/aws-codebuild';
import * as codecommit from 'aws-cdk-lib/aws-codecommit';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { ISecret } from 'aws-cdk-lib/aws-secretsmanager';
import { StringParameter } from 'aws-cdk-lib/aws-ssm';
import * as cr from 'aws-cdk-lib/custom-resources';
import { Construct } from 'constructs';

interface AmplifyHostingProps {
sourceRepo: string;
sourceBranch: string;
appRoot: string;
environment?: {
[name: string]: string;
};
interface SupabaseStudioProps {
sourceBranch?: string;
appRoot?: string;
supabaseUrl: string;
dbSecret: ISecret;
anonKey: StringParameter;
serviceRoleKey: StringParameter;
}

export class AmplifyHosting extends Construct {
export class SupabaseStudio extends Construct {
/** App in Amplify Hosting. It is a collection of branches. */
readonly app: amplify.App;
/** Production branch */
readonly prodBranch: amplify.Branch;
/** URL of production branch */
readonly prodBranchUrl: string;

/** Next.js App Hosting */
constructor(scope: Construct, id: string, props: AmplifyHostingProps) {
/** Next.js app on Amplify Hosting */
constructor(scope: Construct, id: string, props: SupabaseStudioProps) {
super(scope, id);

const { sourceRepo, sourceBranch, appRoot, environment = {} } = props;
const buildImage = 'public.ecr.aws/sam/build-nodejs18.x:latest';
const sourceRepo = 'https://github.com/supabase/supabase.git';
const sourceBranch = props.sourceBranch ?? 'master';
const appRoot = props.appRoot ?? 'studio';
const { supabaseUrl, dbSecret, anonKey, serviceRoleKey } = props;

/** CodeCommit - Source Repository for Amplify Hosting */
const repository = new Repository(this, 'Repository', {
Expand All @@ -46,8 +52,10 @@ export class AmplifyHosting extends Construct {
assumedBy: new iam.ServicePrincipal('amplify.amazonaws.com'),
});

/** Keys of environment variables */
const envKeys = Object.keys(environment);
// Allow the role to access Secret and Parameter
dbSecret.grantRead(role);
anonKey.grantRead(role);
serviceRoleKey.grantRead(role);

/** BuildSpec for Amplify Hosting */
const buildSpec = BuildSpec.fromObjectToYaml({
Expand All @@ -58,11 +66,14 @@ export class AmplifyHosting extends Construct {
phases: {
preBuild: {
commands: [
`env | grep ${envKeys.map(key => `-e ${key}`).join(' ')} >> .env.production`,
'echo POSTGRES_PASSWORD=$(aws secretsmanager get-secret-value --secret-id $DB_SECRET_ARN --query SecretString | jq -r . | jq -r .password) >> .env.production',
'echo SUPABASE_ANON_KEY=$(aws ssm get-parameter --region $SSM_REGION --name $ANON_KEY_NAME --query Parameter.Value) >> .env.production',
'echo SUPABASE_SERVICE_KEY=$(aws ssm get-parameter --region $SSM_REGION --name $SERVICE_KEY_NAME --query Parameter.Value) >> .env.production',
'env | grep -e STUDIO_PG_META_URL >> .env.production',
'env | grep -e SUPABASE_ >> .env.production',
'env | grep -e NEXT_PUBLIC_ >> .env.production',
'yum install -y rsync',
'cd ../',
'npx turbo@1.7.0 prune --scope=studio',
'npx turbo@1.10.3 prune --scope=studio',
'npm clean-install',
],
},
Expand Down Expand Up @@ -104,19 +115,27 @@ export class AmplifyHosting extends Construct {
sourceCodeProvider: new amplify.CodeCommitSourceCodeProvider({ repository }),
buildSpec,
environmentVariables: {
...environment,
// for Amplify Hosting Build
NODE_OPTIONS: '--max-old-space-size=4096',
AMPLIFY_MONOREPO_APP_ROOT: appRoot,
AMPLIFY_DIFF_DEPLOY: 'false',
_CUSTOM_IMAGE: buildImage,
// for Supabase
STUDIO_PG_META_URL: `${supabaseUrl}/pg`,
SUPABASE_URL: `${supabaseUrl}`,
SUPABASE_PUBLIC_URL: `${supabaseUrl}`,
DB_SECRET_ARN: dbSecret.secretArn,
SSM_REGION: anonKey.env.region,
ANON_KEY_NAME: anonKey.parameterName,
SERVICE_KEY_NAME: serviceRoleKey.parameterName,
},
customRules: [
{ source: '/<*>', target: '/index.html', status: amplify.RedirectStatus.NOT_FOUND_REWRITE },
],
});
(this.app.node.defaultChild as cdk.CfnResource).addPropertyOverride('Platform', 'WEB_COMPUTE');

this.app.addEnvironment('NODE_OPTIONS', '--max-old-space-size=4096');
this.app.addEnvironment('AMPLIFY_MONOREPO_APP_ROOT', appRoot);
this.app.addEnvironment('AMPLIFY_DIFF_DEPLOY', 'false');

this.app.addCustomRule({ source: '/<*>', target: '/index.html', status: amplify.RedirectStatus.NOT_FOUND_REWRITE });
/** SSR v2 */
(this.app.node.defaultChild as cdk.CfnResource).addPropertyOverride('Platform', 'WEB_COMPUTE');

this.prodBranch = this.app.addBranch('ProdBranch', {
branchName: 'main',
Expand Down
Loading

0 comments on commit 97c37f7

Please sign in to comment.