SST: Deploy only some stacks

2k Views Asked by At

Here out IaC project structure:

./
├── cdk.context.json
├── package.json
├── package-lock.json
├── README.md
├── sst.json
└── stacks
    ├── common
    │   ├── Msk.js
    │   └── Vpc.js
    ├── index.js
    ├── posiciones
    │   ├── Consumer.js
    │   └── DocumentDB.js
    └── vistas
        ├── Api.js
        └── Database.js

sst.json is:

{
  "name": "rmo-serverless",
  "region": "us-west-2",
  "main": "stacks/index.js"
}

and stacks/index.js:

import { App } from "@serverless-stack/resources";

import { Api } from "./vistas/Api";
import { Database } from "./vistas/Database";
import { Vpc } from "./common/Vpc";
import { Msk } from "./common/Msk";
import { Consumer } from "./posiciones/Consumer";
import { DocumentDB } from "./posiciones/DocumentDB";


/**
 * @param {App} app
 */
export default function (app) {
  app.setDefaultFunctionProps({   //not needed
    runtime: "nodejs14.x",
  });
  app.stack(Vpc)
     .stack(Msk)
     .stack(Database)
     .stack(DocumentDB)
     .stack(Consumer)
     .stack(Api);
}

As I mentioned above, we're infrastructure code (sst) and services code (lambdas), in different repositories.

Currently, we're creating our pipelines. In short, we have two pipelines:

  • 1 pipeline to Deploy indrastructure: documentdb, rds, msk, vpc
  • N pipeline (1 for each) services: lambdas and api gateway

What we are trying to get is that when a service code is pushed on branch, it only re-deploy services related elements, lambdas...

Problem here, is how could we only deploy infrastructure items (documentdb, rds, msk, vpc)? Or how could we deploy only service items (lambdas, api)?

Any suggestions in order to best organize sst project?

1

There are 1 best solutions below

1
On BEST ANSWER

One suggestion is to utilize your stage names. For example, you may have a helper function like this in let's say /utils/index.ts:

/**
 * A conditional helper function, add Stack based on given `stage` name.
 *
 * @param {App} app
 * @param {string} stage
 * @param {any} stack
 * @returns void
 */
export const addStackPerStage = (app, stage, stack) => {
  if (app.stage === stage) {
    app.stack(stack);
  }
};

Then using this helper function like below:

import { App } from "@serverless-stack/resources";

import { Api } from "./vistas/Api";
import { Database } from "./vistas/Database";
import { Vpc } from "./common/Vpc";
import { Msk } from "./common/Msk";
import { Consumer } from "./posiciones/Consumer";
import { DocumentDB } from "./posiciones/DocumentDB";
import { addStackPerStage } from "./utils";

/**
 * @param {App} app
 */
export default function (app) {
  app.setDefaultFunctionProps({   //not needed
    runtime: "nodejs14.x",
  });
  
  // Infrastructure ONLY.
  addStackPerStage(app, "infrastructure-only", Vpc);
  addStackPerStage(app, "infrastructure-only", Msk);
  addStackPerStage(app, "infrastructure-only", Database);
  addStackPerStage(app, "infrastructure-only", DocumentDB);

  // Service 1 Only
  addStackPerStage(app, "service-1-only", Consumer); // use vpc.fromLookup instead
  
  // Service 2 Only
  addStackPerStage(app, "service-2-only", Api); // use vpc.fromLookup instead
}

Then, your script may be used like:

sst deploy --stage=infrastructure-only

And about branch names, you may utilize a npm package like https://www.npmjs.com/package/branch-name. Then, refactor the suggested codebase above, to use 'branch names' instead, as your new 'flag' to conditionally 'append Stack(s)'.

Lastly, I'm answering the best I can based on paragraphs below:

What we are trying to get is that when a service code is pushed on branch, it only re-deploy services related elements, lambdas...

Problem here, is how could we only deploy infrastructure items (documentdb, rds, msk, vpc)? Or how could we deploy only service items (lambdas, api)?

I hope this suggestion helps. As on my end, I use this helper function in the case of Organisational Units and N AWS accounts per OU, also with Resource Access Manager (RAM) etc.

Bonus: I just found out about Stack Sets this week, take a look here if this Construct interests you, https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudformation.CfnStackSet.html. Ideal if you're deploying Stacks by AWS Accounts as well.