diff --git a/cmd/ftl-provisioner-cloudformation/postgres.go b/cmd/ftl-provisioner-cloudformation/postgres.go index ad1421422..570d98818 100644 --- a/cmd/ftl-provisioner-cloudformation/postgres.go +++ b/cmd/ftl-provisioner-cloudformation/postgres.go @@ -71,9 +71,10 @@ func PostgresPostUpdate(ctx context.Context, secrets *secretsmanager.Client, byN return fmt.Errorf("failed to get username and password from secret ARN: %w", err) } - adminEndpoint := endpointToDSN(write.OutputValue, "postgres", 5432, username, password) - - // Connect to postgres without a specific database to create the new one + if err := createPostgresDatabase(ctx, *write.OutputValue, resourceID, username, password); err != nil { + return fmt.Errorf("failed to create postgres database: %w", err) + } + adminEndpoint := endpointToDSN(write.OutputValue, resourceID, 5432, username, password) db, err := sql.Open("pgx", adminEndpoint) if err != nil { return fmt.Errorf("failed to connect to postgres: %w", err) @@ -96,8 +97,7 @@ func PostgresPostUpdate(ctx context.Context, secrets *secretsmanager.Client, byN if _, err := db.ExecContext(ctx, fmt.Sprintf(` GRANT CONNECT ON DATABASE %s TO ftluser; GRANT USAGE ON SCHEMA public TO ftluser; - GRANT USAGE ON SCHEMA public TO ftluser; - GRANT CREATE ON SCHEMA public TO ftluser; + GRANT CREATE ON SCHEMA public TO ftluser; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ftluser; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ftluser; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO ftluser; @@ -110,6 +110,26 @@ func PostgresPostUpdate(ctx context.Context, secrets *secretsmanager.Client, byN return nil } +func createPostgresDatabase(ctx context.Context, endpoint, resourceID, username, password string) error { + adminEndpoint := endpointToDSN(&endpoint, "postgres", 5432, username, password) + + // Connect to postgres without a specific database to create the new one + db, err := sql.Open("pgx", adminEndpoint) + if err != nil { + return fmt.Errorf("failed to connect to postgres: %w", err) + } + defer db.Close() + + // Create the database if it doesn't exist + if _, err := db.ExecContext(ctx, "CREATE DATABASE "+resourceID); err != nil { + // Ignore if database already exists + if !strings.Contains(err.Error(), "already exists") { + return fmt.Errorf("failed to create database: %w", err) + } + } + return nil +} + func updatePostgresOutputs(_ context.Context, to *schemapb.DatabaseRuntime, resourceID string, outputs []types.Output) error { byName, err := outputsByPropertyName(outputs) if err != nil {