Hello friends, I’m back with more questions about ...
# seed
a
Hello friends, I’m back with more questions about BACKEND + FRONTEND deployments… From a previous thread… I want to deploy the entire application every time a PR is created… that means… API + Frontend (ReactJS app). Something that @Frank proposed is to do the deployment from the “after deploy” step, or whatever the last step is called. I liked it, but, will be possible for me, in that step, to pull the API GW URLs where my services were deployed? Asking this due my React app can receive some ENV variables corresponding to my API services, and compile those values during the build. Let me know if this makes any sense.
d
yeah i haven't figured out how to tie in our api env + vercel nextjs deployment either. so this means that the env-per-pr dont work for us yet. however, at least for our qa, uat, and prod envs, all those URLs can be hardcoded.
t
Do you have FE and BE in the same repo?
a
I don’t, I have 2 repos, one for FE and other BE @thdxr.
@Dennis Dang yeah, what I been thinking is to enable one “config screen” where the QA team can put the BE URLs manually, then I have “static FE deployments” where you can switch the backend.
But I want to avoid doing that.
t
This is the classic dependency problem you have a few options. 1. If using multiple repos, the frontend needs to be able to infer where the backend lives. I'd suggest putting your backend deployments behind custom domains. Then on your frontend deploy it can look for a backend at mybranch.dev.mydomain.com or fallback to master.dev.mydomain.com (if the pr doesn't have an associated backend pr) 2. Use a monorepo and deploy it as one stack
a
I like 1, that’s why I was thinking that my FE can infer the BE location from the build process, like… pr1.dev.mydomain.com Where PR1 is a variable from the build step.
But not sure if SEED provides that info to me.
d
you have access to the variables in the post deploy. let me find that thread where i asked frank the exact question
a
Yeah I know some variables, not sure about this one.
wouldnt all you need is the
pr1
part?
t
Also instead of the variable you can query aws for it
a
Yeah @Dennis Dang.
Yeah I been thinking also to use CF info.
CF = cloundformation.
I mean, I can do export / import.
CF can store the information where the BE lives, and then the last step can just pull it.
f
@Adrián Mouly Say you have a FE repo with an
api-stack
and a BE repo with a React app. In the
api
stack, have an output called
API_URL
. Now on Seed, configure the Post-Deploy Phase to be something like:
Copy code
API_URL=$(aws cloudformation describe-stacks --stack-name $SEED_STAGE_NAME-api-stack --query 'Stacks[0].Outputs[0]...')
git clone FE
npm install
npm run build
In essense, you use aws cli to query for the API endpoint, then you can use it as an environment variable above or do a search and replace in ur code before running
npm run build
.
Does this work for you?
a
Interesting.
Yeah this is the CF way, right?
f
Yeah.
a
So, I been also checking how Finch plugin works… might use that to deploy the FE… but it requires an EXISTING s3 bucket… where should I create this bucket?
I mean which step of the build process, should I call CREATE S3 from this last step also?
f
hmm.. does the Finch plugin solve this issue?
Are you thinking of adding 2 apps on Seed, 1 for the frontend and 1 for the backend?
a
No, just 1 app which is the BE, and the “post deploy” should deploy my FE.
What Finch does is automate the deployment of the ReactJS app, I think that’s all.
f
Last time I checked the Finch plugin doesn’t setup CloudFront distribution, and doesn’t have domain support? If you need to setup the CloudFront CDN, the
StaticSite
construct should work for you. Here’s an example for React - https://docs.serverless-stack.com/constructs/StaticSite#creating-a-react-site
a
Nice, going to check it, still didn’t use CDK yet.
r
StaticSite
construct is great! (I just used it) Last time I did frontend deployments, it was a huge pain. With
StaticSite
it's a breeze.
a
Do you have examples @Ryan?
r
Copy code
import * as sst from "@serverless-stack/resources";
import * as fs from 'fs';

export default class FrontendStack extends sst.Stack {
  constructor(scope: <http://sst.App|sst.App>, id: string, props?: sst.StackProps) {
    super(scope, id, props);

    const hostedZone = '<http://mydevhostedzone.com|mydevhostedzone.com>';
    const domain = 'dev';

    fs.writeFileSync(`../../frontend/src/environments/config-prod.json`, JSON.stringify({apiUrl: 'api.' + domain + '.' + hostedZone}));

    const frontend = new sst.StaticSite(this, "StaticSite", {
      path: '../../frontend',
      buildCommand: 'npm run build:prod',
      buildOutput: 'dist/',
      customDomain: {
        hostedZone: hostedZone,
        domainName: domain + '.' + hostedZone
      }
    });
  }
}
It needs to be a bit more flexible, but if the hosted zone and domain come from the environment, that's all that is needed to get a frontend built and deployed that points to the correct backend. It has SSL cert, CDN and the works.
Something it doesn't do (and finch doesn't do either), is leave behind old assets for users that are running the frontend during the new deployment. What that means is that, unless you use service workers, old assets are removed, and users that are currently browsing the app when you deploy a new version may receive some 404 errors. What static site should do IMO is expire old assets after a few days rather than delete them in the s3 bucket. I think that's a CDK issue from memory. You probably won't notice apart from really high traffic sites, but it's a hole in the deployment strategy.