
Lesson Description
The "Deploying with GitHub Actions" Lesson is part of the full, Cloud Infrastructure: Startup to Scale course featured in this preview video. Here's what you'd learn in this lesson:
Erik adds a deploy job to the GitHub Actions that will import the secrets, pull the image built in the earlier action, run the migrations, and promote the image by adding the "latest" tag to it. The image is then pushed to ECR. Later in the course, the promotion will only occur when a commit is merged into main.
Transcript from the "Deploying with GitHub Actions" Lesson
[00:00:00]
>> Erik Reinert: While that's running, we're going to take care of the last thing that we were going to do today anyways that is setting up the deployment process. Now we said right now we want to manage the deployment of the image. We already know that we can do that.
[00:00:19]
We can build the image and push it in CI. That's pretty straightforward. But we also want to make sure that we can migrate the database. Now I want to migrate my Supabase database. That's the goal is to make GitHub actions connect to Supabase and then run the migrations against it.
[00:00:40]
So what we want to do is we want to set up a job that really does the two things that we said. We want to set up a job that will build our image and promote it for us so that we trigger a deployment, but we also want to do a job that will connect out to Supabase and run the the migrations for us as well.
[00:01:00]
To do that, what we're going to do is we're going to add another job in our GitHub Actions. We're going to call this one Deploy. Now, you'll notice that there's a little bit more going on with this one. I'll explain it super quickly. The first thing you'll notice is actually a brand new key called concurrency.
[00:01:21]
This is a GitHub Action specific feature that's really nice where it will make sure that only one deployment happens at a given time in the repo, no matter what. For example, if two merges get made to master main at the same time, this one will run first and the other one will wait until that one is successful or that one will stop until it fails or whatever.
[00:01:47]
But this is a really nice way to make sure that you don't have multiple deployments running and overlapping each other and things like that. The next thing is, because this is so credential heavy and so credential specific, we're just sharing all the environment variables for all the job here.
[00:02:06]
I'm not adding it to just the one step. I'm doing it for pretty much everything. Then you'll see that we have our normal things underneath it like needs and runs on. But you'll notice that I have something commented out here called if so right now it's commented out, but in the future this would be uncommented by default.
[00:02:27]
Can anyone tell me why? But it only does it whenever you push the main, exactly. Yeah, so this is our deploy step, right? We only want this to run on the main branch, and so we're using the if key here, telling GitHub Actions, hey, we only want you to run if it's the main branch effectively, right?
[00:02:51]
The next thing we want to do really quickly, and it's actually nice that I've already got this set up, is we want to go to GitHub actions, and we want to add the other secrets and variables that are needed to run the job. We know that we need our goose DB string and our goose driver, so let's go ahead and add those.
[00:03:11]
So the same exact value, if we go to ssm, I'll do this with you because I got to update it too. Parameter store fem fd service and then postgres, this is my postgres URL that I want so I can copy this. Let me just grab this really quick, grab this, and then I'm just going to paste.
[00:03:51]
I'm going to create a new value called goose DB string, save that value in. This is another reason why it's helpful to not be behind a network or anything like that as well, because we don't have to solve the problem of how does the runner access the RDS instance?
[00:04:15]
Which is the common thing whenever you do your own self hosted database Here we don't have to really worry about that at all. It will go ahead and take care of it for us. Now what we want to do is we want to commit our new, our new job, right?
[00:04:36]
So I'm going to do commit, and we'll say setup, deploy job nice, and we'll push this up. Now again, normally this would not run on this branch, but because I commented out the, you know, I commented out the if statement, it will. So if you've ever, you know, or if you're in the future, you're like, man, I need to debug this step.
[00:05:01]
Just use that, just comment that out, let it run on your job. Debug, debug, debug. Once it's working, remove the comment and you should be good to go. So the goal now should be that it's going to build the image, push it up, it's going to go to the test job, pull that image down, build it, or I'm sorry, not build it, run the test, the migrations against it, then it's going to use that exact same image again in the deploy step to run those migrations as well.
[00:05:28]
Now what's really dope about that is now we are testing our migrations in the pipeline. Then we're also using the pipeline to run those exact same migrations against our Database, that's really the closed again. We're wrapping up this phase. That's the first closed loop that we just made where now we have a database.
[00:05:50]
It's managed by migrations, we know that we should be always making only working changes to the database, and we're testing that, right? The second closed loop will be the promotion process. We said earlier that you guys would have to do the manual part of building locally and pushing to trigger that deployment.
[00:06:10]
Well, we don't wanna do that anymore, we just want it to be merge and walk away. And so now when we merge and walk away, we also get the benefit of that promotion happening. We still get to build every time we make a change, but now the build and the push are separate from each other and the promotion to where now it's like, okay, well, we only promote on main, but we get to still build in every branch, we get to test in every branch, and we know that everything's working.
[00:06:37]
So there's our job, it's running. Big money, big money, big money. Yeah, let's hope, right? Yeah. Hey, we worked. All right, so basically, we pulled our image, we pulled that tagged version of it, we then ran our migration. So we didn't actually promote our image until the migrations ran.
[00:07:07]
That's another thing to note. We didn't trigger the update until the migration actually happened because if the migration didn't work, then we wouldn't want to deploy the service, right? So we make sure the migrations run first. It connects out to Supabase, actually runs the migrations, and then the last thing it does is it promotes that image.
[00:07:29]
And so you can see here, here's our tag, here's latest, and then I should be able to. Now if I go in here, App runner. All right, cool. Then there you go. You can see I actually already have my deployment in process. If I scroll down here, you can see that it's.
[00:07:55]
Well, I don't know why it's rollbacking, but it's starting my deployment and taking care of my deployment process. So now, this will go through, it'll make sure that it's successful, and then there you go, I just deployed. So now, we have a complete end to end CI CD that's running in our pipeline.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops