1
00:00:00,000 --> 00:00:02,680
Today's topic is one that almost everyone is heard of,

2
00:00:02,680 --> 00:00:05,000
but very few people can actually explain.

3
00:00:05,000 --> 00:00:06,000
Githops.

4
00:00:06,000 --> 00:00:07,840
You've probably seen it mentioned in job postings,

5
00:00:07,840 --> 00:00:10,000
conference talks, or Azure documentation.

6
00:00:10,000 --> 00:00:11,040
But what exactly is it?

7
00:00:11,040 --> 00:00:13,200
Is it just another DevOps buzzword,

8
00:00:13,200 --> 00:00:14,840
or is it something fundamentally different?

9
00:00:14,840 --> 00:00:16,040
Here's the short version.

10
00:00:16,040 --> 00:00:18,280
Githops is an operating model where Git becomes

11
00:00:18,280 --> 00:00:21,200
the single source of truth for your entire infrastructure.

12
00:00:21,200 --> 00:00:24,320
Not just your application code, but everything that runs it.

13
00:00:24,320 --> 00:00:25,560
By the end of this episode,

14
00:00:25,560 --> 00:00:27,200
you'll understand what Githops actually is,

15
00:00:27,200 --> 00:00:30,040
why it's become the standard for managing Kubernetes on Azure,

16
00:00:30,040 --> 00:00:34,280
and how it makes rollbacks as simple as a single command.

17
00:00:34,280 --> 00:00:36,840
The old way, manual deployments and configuration drift.

18
00:00:36,840 --> 00:00:38,600
Let's start with the problem GitHub solves.

19
00:00:38,600 --> 00:00:41,120
Imagine you're managing a Kubernetes cluster on Azure.

20
00:00:41,120 --> 00:00:42,560
You have developers pushing code,

21
00:00:42,560 --> 00:00:44,880
a CI pipeline building container images,

22
00:00:44,880 --> 00:00:47,960
and someone runs, Quebec will apply to deploy those images.

23
00:00:47,960 --> 00:00:49,560
Maybe you, maybe a teammate,

24
00:00:49,560 --> 00:00:51,280
or you click a button in Azure DevOps,

25
00:00:51,280 --> 00:00:52,960
and either way the deployment happens.

26
00:00:52,960 --> 00:00:54,480
That works fine until it doesn't.

27
00:00:54,480 --> 00:00:55,680
Here's what happens next.

28
00:00:55,680 --> 00:00:57,920
Someone on your team needs to fix a QuickBug,

29
00:00:57,920 --> 00:00:59,640
so they SSH into a node,

30
00:00:59,640 --> 00:01:00,720
use the Azure portal,

31
00:01:00,720 --> 00:01:03,200
or run Quebec to edit directly on a deployment.

32
00:01:03,200 --> 00:01:05,600
They make a small change like a config map tweak,

33
00:01:05,600 --> 00:01:07,280
or a different environment variable,

34
00:01:07,280 --> 00:01:08,600
and it seems harmless.

35
00:01:08,600 --> 00:01:10,520
Or so they think, the problem is,

36
00:01:10,520 --> 00:01:12,360
that change never made it back to Git,

37
00:01:12,360 --> 00:01:14,240
so your cluster now has a configuration

38
00:01:14,240 --> 00:01:16,320
that doesn't match what's in your repository.

39
00:01:16,320 --> 00:01:18,200
That's called configuration drift.

40
00:01:18,200 --> 00:01:19,960
Drift is a silent killer because it works fine

41
00:01:19,960 --> 00:01:21,200
until the next deployment,

42
00:01:21,200 --> 00:01:22,680
when someone runs Quebec to apply

43
00:01:22,680 --> 00:01:25,800
with the original manifest and overrides that QuickFix.

44
00:01:25,800 --> 00:01:28,080
Or worse, the drift causes unexpected behavior

45
00:01:28,080 --> 00:01:29,280
that nobody can explain.

46
00:01:29,280 --> 00:01:30,640
You start debugging, check the logs,

47
00:01:30,640 --> 00:01:32,040
look at the YAML and Git,

48
00:01:32,040 --> 00:01:32,920
and nothing seems wrong,

49
00:01:32,920 --> 00:01:34,720
but the cluster is doing something different.

50
00:01:34,720 --> 00:01:36,760
You have no idea what changed when it changed,

51
00:01:36,760 --> 00:01:37,840
or who changed it.

52
00:01:37,840 --> 00:01:38,840
I've seen this happen.

53
00:01:38,840 --> 00:01:40,840
A teammate, SSH, into a node,

54
00:01:40,840 --> 00:01:42,440
tweaks a config to test something,

55
00:01:42,440 --> 00:01:44,960
forgets to revert it and goes home.

56
00:01:44,960 --> 00:01:46,680
The next day, a deployment breaks,

57
00:01:46,680 --> 00:01:48,320
and nobody can explain why.

58
00:01:48,320 --> 00:01:49,600
The Git repo looks clean,

59
00:01:49,600 --> 00:01:50,760
but the cluster is a mess,

60
00:01:50,760 --> 00:01:53,520
and your stack spending hours trying to figure out what happened.

61
00:01:53,520 --> 00:01:54,840
So here's the question.

62
00:01:54,840 --> 00:01:56,920
What if there was a way to force the cluster

63
00:01:56,920 --> 00:01:58,520
to always match what's in Git?

64
00:01:58,520 --> 00:02:01,160
What if you could guarantee that whatever is in your repository

65
00:02:01,160 --> 00:02:02,800
is exactly what's running in production?

66
00:02:02,800 --> 00:02:04,960
That's the core idea behind GitOps.

67
00:02:04,960 --> 00:02:06,360
What GitOps actually is.

68
00:02:06,360 --> 00:02:07,720
So what exactly is GitOps?

69
00:02:07,720 --> 00:02:10,160
Here's the simplest definition I can give you.

70
00:02:10,160 --> 00:02:11,960
Git becomes your single source of truth,

71
00:02:11,960 --> 00:02:13,080
not just for your code,

72
00:02:13,080 --> 00:02:15,520
but for everything your infrastructure needs to run.

73
00:02:15,520 --> 00:02:17,760
Every configuration, every deployment, manifest,

74
00:02:17,760 --> 00:02:19,320
every environment variable,

75
00:02:19,320 --> 00:02:20,880
it all lives in Git.

76
00:02:20,880 --> 00:02:23,280
Nothing runs on your cluster unless it's defined there.

77
00:02:23,280 --> 00:02:25,040
Now, GitOps isn't a tool you can buy.

78
00:02:25,040 --> 00:02:27,880
It's an operating model, like DevOps or DevSecOps.

79
00:02:27,880 --> 00:02:29,160
A set of principles that guide

80
00:02:29,160 --> 00:02:31,320
how you manage your infrastructure.

81
00:02:31,320 --> 00:02:34,080
The open GitOps standard lays out four core principles,

82
00:02:34,080 --> 00:02:35,520
and I want to walk through each one.

83
00:02:35,520 --> 00:02:37,400
First, your system has to be declarative.

84
00:02:37,400 --> 00:02:39,320
That means you describe the end state,

85
00:02:39,320 --> 00:02:40,720
not the steps to get there.

86
00:02:40,720 --> 00:02:42,200
So instead of writing a script that says,

87
00:02:42,200 --> 00:02:44,640
"Created deployment, scale it to five replicas,

88
00:02:44,640 --> 00:02:47,040
expose port 8080, you write a YAML file

89
00:02:47,040 --> 00:02:49,960
that says I want five replicas on port 8080,

90
00:02:49,960 --> 00:02:51,400
and the system figures out the steps.

91
00:02:51,400 --> 00:02:52,400
That's declarative.

92
00:02:52,400 --> 00:02:54,000
Second, it must be versioned.

93
00:02:54,000 --> 00:02:56,640
Every change you make to your cluster state is a commit in Git.

94
00:02:56,640 --> 00:02:59,400
So you get a complete history who changed what, when and why,

95
00:02:59,400 --> 00:03:01,440
no more guessing or digging through logs.

96
00:03:01,440 --> 00:03:03,360
Third, changes are pulled automatically.

97
00:03:03,360 --> 00:03:05,480
The cluster reaches out to Git to see what's new.

98
00:03:05,480 --> 00:03:07,240
Later, I'll explain why this matters so much.

99
00:03:07,240 --> 00:03:09,680
And fourth, the system is continuously reconciled.

100
00:03:09,680 --> 00:03:11,760
There's a software agent running inside your cluster

101
00:03:11,760 --> 00:03:14,840
that constantly compares what's in Git to what's actually running.

102
00:03:14,840 --> 00:03:16,760
If they don't match, it fixes the difference.

103
00:03:16,760 --> 00:03:18,080
That's the reconciliation loop.

104
00:03:18,080 --> 00:03:19,280
Think of it this way.

105
00:03:19,280 --> 00:03:20,960
Git is your architect's blueprint.

106
00:03:20,960 --> 00:03:23,680
It describes exactly what the building should look like.

107
00:03:23,680 --> 00:03:25,360
Kubernetes is the construction site.

108
00:03:25,360 --> 00:03:27,520
And the GitOps operator, that's the foreman.

109
00:03:27,520 --> 00:03:29,680
He walks around with the blueprint, checking every wall,

110
00:03:29,680 --> 00:03:30,880
every beam, every window.

111
00:03:30,880 --> 00:03:33,000
If something doesn't match, he fixes it.

112
00:03:33,000 --> 00:03:35,640
Suppose someone on the crew makes an unauthorized change.

113
00:03:35,640 --> 00:03:37,400
He spots it and reverts it.

114
00:03:37,400 --> 00:03:39,640
The blueprint is always the source of truth.

115
00:03:39,640 --> 00:03:41,200
But here's where the real shift happens,

116
00:03:41,200 --> 00:03:42,920
how deployments actually work.

117
00:03:42,920 --> 00:03:45,560
In traditional CI/CD, you push changes to the cluster.

118
00:03:45,560 --> 00:03:47,480
In GitOps, the cluster pulls them.

119
00:03:47,480 --> 00:03:50,360
And that difference is more important than it sounds.

120
00:03:50,360 --> 00:03:52,400
Pull-based deployments versus push-based.

121
00:03:52,400 --> 00:03:54,200
Let's talk about how deployments actually work

122
00:03:54,200 --> 00:03:56,480
because this is where GitOps changes everything.

123
00:03:56,480 --> 00:03:59,840
In the traditional push-based model, your CI pipeline does everything.

124
00:03:59,840 --> 00:04:03,160
Azure Pipelines, Jenkins, GitHub Actions.

125
00:04:03,160 --> 00:04:05,280
It builds the container, runs tests,

126
00:04:05,280 --> 00:04:08,640
and then pushes that image directly to your Kubernetes cluster.

127
00:04:08,640 --> 00:04:10,880
The pipeline holds credentials that give it direct access

128
00:04:10,880 --> 00:04:12,200
to the cluster API.

129
00:04:12,200 --> 00:04:15,080
It says, here's the new deployment, apply it now.

130
00:04:15,080 --> 00:04:17,360
And that works, but it creates a security problem.

131
00:04:17,360 --> 00:04:18,200
Here's the thing.

132
00:04:18,200 --> 00:04:19,880
If that pipeline gets compromised,

133
00:04:19,880 --> 00:04:22,600
someone injects a malicious step, a token leaks,

134
00:04:22,600 --> 00:04:24,320
a dependency gets hijacked.

135
00:04:24,320 --> 00:04:27,440
That pipeline has a direct line to your production cluster.

136
00:04:27,440 --> 00:04:29,760
It can destroy deployments, delete namespaces,

137
00:04:29,760 --> 00:04:32,160
change configurations, all with the permissions

138
00:04:32,160 --> 00:04:33,800
you gave it to do its job.

139
00:04:33,800 --> 00:04:35,040
Now look at the GitOps model.

140
00:04:35,040 --> 00:04:36,000
The flow starts the same.

141
00:04:36,000 --> 00:04:38,280
CI builds the container and pushes it to a registry

142
00:04:38,280 --> 00:04:39,600
like Azure Container Registry.

143
00:04:39,600 --> 00:04:40,560
That's where CI stops.

144
00:04:40,560 --> 00:04:41,800
It does not touch the cluster.

145
00:04:41,800 --> 00:04:44,120
Instead, CI updates a Git repository

146
00:04:44,120 --> 00:04:45,560
with a new image tag.

147
00:04:45,560 --> 00:04:49,000
It changes a single line in a YAML file, the image version,

148
00:04:49,000 --> 00:04:50,120
and commits that change.

149
00:04:50,120 --> 00:04:50,640
That's it.

150
00:04:50,640 --> 00:04:51,920
No direct cluster access.

151
00:04:51,920 --> 00:04:54,360
Then the GitOps operator running inside your cluster

152
00:04:54,360 --> 00:04:55,360
sees that change.

153
00:04:55,360 --> 00:04:57,920
It pulls the latest state from Git and applies it.

154
00:04:57,920 --> 00:05:00,440
The cluster reaches out to Git, not the other way around.

155
00:05:00,440 --> 00:05:01,840
This is the pool-based model.

156
00:05:01,840 --> 00:05:04,520
Your cluster never exposes its API to external systems.

157
00:05:04,520 --> 00:05:05,760
It only pulls from Git.

158
00:05:05,760 --> 00:05:07,640
If someone compromises your CI pipeline,

159
00:05:07,640 --> 00:05:10,040
the worst they can do is change and manifest in a repository.

160
00:05:10,040 --> 00:05:11,760
They can't touch the cluster directly.

161
00:05:11,760 --> 00:05:13,600
The operator decides what to apply and when.

162
00:05:13,600 --> 00:05:14,720
There's another benefit too.

163
00:05:14,720 --> 00:05:16,600
You decouple building from deploying.

164
00:05:16,600 --> 00:05:19,520
CI does what it's good at, building, testing, scanning.

165
00:05:19,520 --> 00:05:21,360
The GitOps operator handles deployment.

166
00:05:21,360 --> 00:05:22,960
Each system focuses on one job.

167
00:05:22,960 --> 00:05:25,160
If the build fails, nothing changes in the cluster.

168
00:05:25,160 --> 00:05:27,880
If the deployment fails, the operator retries or alerts you.

169
00:05:27,880 --> 00:05:29,000
Clean separation.

170
00:05:29,000 --> 00:05:31,240
So instead of a pipeline pushing changes into your cluster,

171
00:05:31,240 --> 00:05:33,520
your cluster pulls its desired state from Git.

172
00:05:33,520 --> 00:05:36,640
That simple inversion makes your infrastructure more secure,

173
00:05:36,640 --> 00:05:40,560
more auditable, and harder to break by accident.

174
00:05:40,560 --> 00:05:42,080
The reconciliation loop.

175
00:05:42,080 --> 00:05:44,080
So how does the operator know when to update?

176
00:05:44,080 --> 00:05:45,760
It doesn't wait for a notification.

177
00:05:45,760 --> 00:05:47,120
It runs a continuous loop.

178
00:05:47,120 --> 00:05:50,320
Watch Git, compared to the cluster, apply changes if needed,

179
00:05:50,320 --> 00:05:52,200
then do it again and again forever.

180
00:05:52,200 --> 00:05:53,960
This is called the reconciliation loop.

181
00:05:53,960 --> 00:05:56,360
It runs constantly every few seconds or minutes,

182
00:05:56,360 --> 00:05:57,960
depending on your configuration.

183
00:05:57,960 --> 00:05:59,680
The operator never stops watching.

184
00:05:59,680 --> 00:06:01,560
Think of it like a thermostat in your house.

185
00:06:01,560 --> 00:06:04,360
You set the desired temperature, say 21 degrees,

186
00:06:04,360 --> 00:06:06,920
the thermostat constantly checks the actual temperature.

187
00:06:06,920 --> 00:06:09,360
If it drops below 21, the heating turns on.

188
00:06:09,360 --> 00:06:11,080
If it goes above the heating turns off,

189
00:06:11,080 --> 00:06:13,080
it keeps adjusting to match your setting.

190
00:06:13,080 --> 00:06:14,800
The GitOps operator works the same way.

191
00:06:14,800 --> 00:06:17,680
Git holds the desired state, the cluster has the actual state,

192
00:06:17,680 --> 00:06:20,480
and the operator compares them continuously making adjustments.

193
00:06:20,480 --> 00:06:22,000
So what happens when someone manually

194
00:06:22,000 --> 00:06:23,480
edits a deployment in the cluster?

195
00:06:23,480 --> 00:06:26,240
Maybe they run Quebecal Edit to change a replica count.

196
00:06:26,240 --> 00:06:27,840
The operator detects that difference

197
00:06:27,840 --> 00:06:29,760
on its next reconciliation cycle.

198
00:06:29,760 --> 00:06:32,520
The cluster now has three replicas, but Git says five.

199
00:06:32,520 --> 00:06:34,480
So the operator applies the Git defined state

200
00:06:34,480 --> 00:06:36,600
and the cluster goes back to five replicas.

201
00:06:36,600 --> 00:06:37,800
The unauthorized change is gone.

202
00:06:37,800 --> 00:06:39,440
What happens when you push a change to Git?

203
00:06:39,440 --> 00:06:40,480
Same process.

204
00:06:40,480 --> 00:06:42,760
The operator detects the difference and applies it.

205
00:06:42,760 --> 00:06:45,120
A developer merges a PR that updates the image version

206
00:06:45,120 --> 00:06:47,360
from V1.2 to V1.3.

207
00:06:47,360 --> 00:06:50,480
The operator sees the new manifest, pulls the new image,

208
00:06:50,480 --> 00:06:52,240
and spins up the new pods.

209
00:06:52,240 --> 00:06:54,400
Within seconds, the cluster matches Git again.

210
00:06:54,400 --> 00:06:56,720
Now, there's an important distinction here.

211
00:06:56,720 --> 00:06:58,560
If a pod crashes, the operator doesn't care.

212
00:06:58,560 --> 00:07:01,440
That's Kubernetes job handled by the replica set controller.

213
00:07:01,440 --> 00:07:04,040
The GitOps operator only cares about the configuration.

214
00:07:04,040 --> 00:07:08,200
If the deployment manifest says five replicas, image V1.3,

215
00:07:08,200 --> 00:07:11,000
and the cluster has five replicas running V1.3,

216
00:07:11,000 --> 00:07:14,440
the operator is happy, it doesn't care if a specific pod restarted.

217
00:07:14,440 --> 00:07:16,240
That's normal Kubernetes behavior.

218
00:07:16,240 --> 00:07:17,840
But if someone changes the manifest in Git

219
00:07:17,840 --> 00:07:19,400
or if someone changes the cluster directly

220
00:07:19,400 --> 00:07:21,320
and creates drift, the operator acts.

221
00:07:21,320 --> 00:07:22,880
That's what makes GitOps self-healing.

222
00:07:22,880 --> 00:07:24,240
It doesn't just deploy changes.

223
00:07:24,240 --> 00:07:25,840
It actively prevents your infrastructure

224
00:07:25,840 --> 00:07:27,960
from drifting away from what's defined.

225
00:07:27,960 --> 00:07:30,560
So you need a GitOps operator running in your cluster.

226
00:07:30,560 --> 00:07:32,880
That's where Argo CD and Flux come in.

227
00:07:32,880 --> 00:07:34,360
Argo CD versus Flux.

228
00:07:34,360 --> 00:07:36,680
So you need a GitOps operator

229
00:07:36,680 --> 00:07:39,320
and you have two main choices, both excellent.

230
00:07:39,320 --> 00:07:42,520
Argo CD and Flux are both CNCF graduated projects,

231
00:07:42,520 --> 00:07:44,040
meaning they've passed the highest bar

232
00:07:44,040 --> 00:07:47,000
for stability, community, and production readiness.

233
00:07:47,000 --> 00:07:49,480
But they approach the same job from different angles.

234
00:07:49,480 --> 00:07:51,160
Argo CD was originally built by Intuit

235
00:07:51,160 --> 00:07:52,640
and it comes with a web UI.

236
00:07:52,640 --> 00:07:55,080
When you install Argo CD, you get a dashboard

237
00:07:55,080 --> 00:07:57,720
where you can see every application, its sync status,

238
00:07:57,720 --> 00:07:59,640
its health, and its deployment history.

239
00:07:59,640 --> 00:08:02,640
You can click around view diffs between Git and the cluster,

240
00:08:02,640 --> 00:08:05,080
manually trigger things and approve changes.

241
00:08:05,080 --> 00:08:07,400
It's designed for teams that want visual dashboards

242
00:08:07,400 --> 00:08:08,960
and manual control points.

243
00:08:08,960 --> 00:08:11,520
Flux came from Weaveworks and it's more modular.

244
00:08:11,520 --> 00:08:13,160
There's no UI by default.

245
00:08:13,160 --> 00:08:14,520
You work from the command line

246
00:08:14,520 --> 00:08:17,120
and you define everything as Kubernetes custom resources.

247
00:08:17,120 --> 00:08:20,560
You create a Git repository object that says, "Watch this repo"

248
00:08:20,560 --> 00:08:23,640
and a customization object that says, "Apply this path."

249
00:08:23,640 --> 00:08:25,360
Flux picks it up in reconciles.

250
00:08:25,360 --> 00:08:27,480
It forces you to embrace Git native workflows

251
00:08:27,480 --> 00:08:29,680
because there's no dashboard to fall back on.

252
00:08:29,680 --> 00:08:31,280
Now here's what matters for Azure users.

253
00:08:31,280 --> 00:08:33,000
Flux is the default GitOps option

254
00:08:33,000 --> 00:08:34,600
on Azure Kubernetes service.

255
00:08:34,600 --> 00:08:37,560
Microsoft built the native integration around Flux V2.

256
00:08:37,560 --> 00:08:39,560
When you enable GitOps on an AKS cluster

257
00:08:39,560 --> 00:08:42,520
through the Azure portal, you're using Flux under the hood.

258
00:08:42,520 --> 00:08:45,120
Azure Arc also uses Flux for multi cluster management.

259
00:08:45,120 --> 00:08:46,440
So if you're an Azure engineer,

260
00:08:46,440 --> 00:08:48,120
Flux is the natural starting point.

261
00:08:48,120 --> 00:08:49,840
But Argo CD has its own strengths.

262
00:08:49,840 --> 00:08:52,040
It's more popular for platform engineering scenarios

263
00:08:52,040 --> 00:08:53,440
where you want a central control plane

264
00:08:53,440 --> 00:08:54,880
managing multiple clusters.

265
00:08:54,880 --> 00:08:56,320
The UI makes it easier for teams

266
00:08:56,320 --> 00:08:58,320
that aren't comfortable with the command line.

267
00:08:58,320 --> 00:09:00,280
And it integrates tightly with Argo rollouts

268
00:09:00,280 --> 00:09:02,280
for progressive delivery like Canary deployments,

269
00:09:02,280 --> 00:09:04,080
blue green deployments, that kind of thing.

270
00:09:04,080 --> 00:09:05,960
The key architectural difference is this.

271
00:09:05,960 --> 00:09:08,120
Argo CD runs as a standalone application

272
00:09:08,120 --> 00:09:09,720
with its own API server.

273
00:09:09,720 --> 00:09:11,960
Flux runs as a set of Kubernetes controllers

274
00:09:11,960 --> 00:09:14,160
more deeply embedded in the cluster itself.

275
00:09:14,160 --> 00:09:17,000
Flux feels like part of your Kubernetes control plane

276
00:09:17,000 --> 00:09:19,560
while Argo CD feels like a separate platform sitting

277
00:09:19,560 --> 00:09:20,320
on top of it.

278
00:09:20,320 --> 00:09:22,120
Flux also relies heavily on customize,

279
00:09:22,120 --> 00:09:24,280
which is a Kubernetes native templating tool.

280
00:09:24,280 --> 00:09:27,640
Argo CD can use customized Helm or plain YAML.

281
00:09:27,640 --> 00:09:30,440
Both support Helm, but Flux has a dedicated Helm controller

282
00:09:30,440 --> 00:09:32,600
that handles Helm releases natively.

283
00:09:32,600 --> 00:09:33,560
There's no wrong choice here.

284
00:09:33,560 --> 00:09:35,120
Both tools do the same job.

285
00:09:35,120 --> 00:09:38,120
But for Azure engineers, Flux is the path of least resistance.

286
00:09:38,120 --> 00:09:40,120
You can enable get-ups with Flux in a few clicks

287
00:09:40,120 --> 00:09:42,920
through the Azure portal, pointed at a Git repo,

288
00:09:42,920 --> 00:09:43,960
and it starts syncing.

289
00:09:43,960 --> 00:09:47,240
No additional installation, no separate server to manage.

290
00:09:47,240 --> 00:09:50,760
GitOps on Azure, AKS, Azure Arc, and Azure DevOps.

291
00:09:50,760 --> 00:09:52,080
So what does this actually look like

292
00:09:52,080 --> 00:09:53,520
when you tie it together with Azure?

293
00:09:53,520 --> 00:09:54,720
Let's start with AKS.

294
00:09:54,720 --> 00:09:57,320
Azure Kubernetes service has built-in GitHub support

295
00:09:57,320 --> 00:09:58,640
using Flux V2.

296
00:09:58,640 --> 00:10:01,000
In the Azure portal, you go to your cluster,

297
00:10:01,000 --> 00:10:03,960
find the GitOps section, and configure it by pointing it

298
00:10:03,960 --> 00:10:05,480
at a Git repository.

299
00:10:05,480 --> 00:10:07,760
Azure Repos GitHub anywhere.

300
00:10:07,760 --> 00:10:10,840
Flux starts watching and whatever manifests you put in that repo

301
00:10:10,840 --> 00:10:12,840
get applied to your cluster automatically.

302
00:10:12,840 --> 00:10:14,200
But AKS is just one piece.

303
00:10:14,200 --> 00:10:17,600
Azure Arc extends GitOps to clusters that aren't in Azure.

304
00:10:17,600 --> 00:10:20,200
On-premises, in other clouds, or at the edge.

305
00:10:20,200 --> 00:10:22,360
Connect them to Azure Arc, and you manage them all

306
00:10:22,360 --> 00:10:24,240
with the same GitOps configuration.

307
00:10:24,240 --> 00:10:26,640
One repo, many clusters, consistent state everywhere.

308
00:10:26,640 --> 00:10:27,640
That's what Arc does.

309
00:10:27,640 --> 00:10:28,920
Now let's talk about the pipeline.

310
00:10:28,920 --> 00:10:31,200
Azure DevOps integrates naturally with this model,

311
00:10:31,200 --> 00:10:32,600
and here's the common patent.

312
00:10:32,600 --> 00:10:35,280
Your source code lives in Azure Repos or GitHub,

313
00:10:35,280 --> 00:10:37,400
and Azure Pipelines handles CI.

314
00:10:37,400 --> 00:10:41,080
It builds the container image, runs tests, scans for vulnerabilities,

315
00:10:41,080 --> 00:10:43,640
and pushes the image to Azure container registry.

316
00:10:43,640 --> 00:10:46,200
Then the pipeline updates the manifests in your GitOps repo

317
00:10:46,200 --> 00:10:48,960
by changing the image tag from V1.2 to V1.3,

318
00:10:48,960 --> 00:10:50,320
commits that change and pushes it.

319
00:10:50,320 --> 00:10:51,000
That's it.

320
00:10:51,000 --> 00:10:52,920
The pipeline never touches the cluster.

321
00:10:52,920 --> 00:10:55,880
Flux running inside AKS detects the change in Git,

322
00:10:55,880 --> 00:10:58,320
pulls the new manifest, sees the updated image tag,

323
00:10:58,320 --> 00:10:59,720
and applies the deployment.

324
00:10:59,720 --> 00:11:01,960
New pods spin up and the cluster reconciles.

325
00:11:01,960 --> 00:11:04,400
You can use GitHub actions instead of Azure Pipelines

326
00:11:04,400 --> 00:11:05,440
if you prefer.

327
00:11:05,440 --> 00:11:06,640
The patent is the same.

328
00:11:06,640 --> 00:11:09,440
CI handles the build, updates the manifests,

329
00:11:09,440 --> 00:11:11,640
and the GitOps operator handles the deployment.

330
00:11:11,640 --> 00:11:13,680
The tool doesn't matter, the model does.

331
00:11:13,680 --> 00:11:14,840
Here's an important detail.

332
00:11:14,840 --> 00:11:16,840
You never store secrets directly in Git,

333
00:11:16,840 --> 00:11:19,960
not API keys, not connection strings, not certificates.

334
00:11:19,960 --> 00:11:22,720
Even in a private repository secrets in Git are a risk.

335
00:11:22,720 --> 00:11:25,960
Instead, use Azure Key Vault or an external secrets operator.

336
00:11:25,960 --> 00:11:28,160
The manifest references the secret by name,

337
00:11:28,160 --> 00:11:30,160
and the operator pulls the actual value

338
00:11:30,160 --> 00:11:31,760
from the Vault at deploy time.

339
00:11:31,760 --> 00:11:33,440
You can also layer policy on top.

340
00:11:33,440 --> 00:11:35,400
Azure Policy with Gatekeeper can enforce rules

341
00:11:35,400 --> 00:11:37,480
like no privileged containers,

342
00:11:37,480 --> 00:11:40,680
or only use approved container registries.

343
00:11:40,680 --> 00:11:43,640
If someone tries to deploy a manifest that violates policy,

344
00:11:43,640 --> 00:11:46,000
Gatekeeper blocks it before it reaches the cluster.

345
00:11:46,000 --> 00:11:47,640
The real world benefit here is scale.

346
00:11:47,640 --> 00:11:51,120
With 50 AKS clusters, you don't manage each one individually.

347
00:11:51,120 --> 00:11:54,480
Define the desired state in a single Git repo,

348
00:11:54,480 --> 00:11:57,200
and every cluster reconciles to that state.

349
00:11:57,200 --> 00:11:59,320
Add a new cluster, point it at the repo,

350
00:11:59,320 --> 00:12:00,640
and it configures itself.

351
00:12:00,640 --> 00:12:03,080
Need to update a configuration across all clusters,

352
00:12:03,080 --> 00:12:04,440
change one file in Git,

353
00:12:04,440 --> 00:12:06,400
and the operators handle the rest.

354
00:12:06,400 --> 00:12:08,520
That's the promise of GitOps on Azure.

355
00:12:08,520 --> 00:12:11,400
One source of truth, many clusters, no drift.

356
00:12:11,400 --> 00:12:13,400
The key benefits.

357
00:12:13,400 --> 00:12:14,960
So all of this sounds good in theory,

358
00:12:14,960 --> 00:12:16,600
but what does it actually mean for your team?

359
00:12:16,600 --> 00:12:19,000
Let's start with the one that gets everyone's attention.

360
00:12:19,000 --> 00:12:20,600
Rollbacks become trivial.

361
00:12:20,600 --> 00:12:22,040
A bad deployment goes out,

362
00:12:22,040 --> 00:12:25,160
your application starts throwing errors, users are complaining.

363
00:12:25,160 --> 00:12:27,360
In the old world, you'd scramble to find the last known

364
00:12:27,360 --> 00:12:30,120
good configuration, run a series of manual commands,

365
00:12:30,120 --> 00:12:31,640
and pray you didn't miss something.

366
00:12:31,640 --> 00:12:33,880
In GitOps, you revert the Git commit.

367
00:12:33,880 --> 00:12:35,800
That's it, one command.

368
00:12:35,800 --> 00:12:38,400
The operator sees the revert, pulls the previous state,

369
00:12:38,400 --> 00:12:40,400
and the cluster goes back to what was working before.

370
00:12:40,400 --> 00:12:44,160
No need to SSH in, no coupactal, and definitely no panic.

371
00:12:44,160 --> 00:12:46,040
Audit trail is built in automatically.

372
00:12:46,040 --> 00:12:48,360
Every change to your infrastructure is a commit.

373
00:12:48,360 --> 00:12:49,840
You know who made it when they made it

374
00:12:49,840 --> 00:12:51,320
and exactly what they changed.

375
00:12:51,320 --> 00:12:53,520
No more guessing whether someone edited a deployment

376
00:12:53,520 --> 00:12:55,320
at 2am and forgot to mention it.

377
00:12:55,320 --> 00:12:57,720
The history is there, immutable, and reviewable.

378
00:12:57,720 --> 00:13:00,080
Self-healing is another one that sounds like magic

379
00:13:00,080 --> 00:13:01,320
until you see it work.

380
00:13:01,320 --> 00:13:03,640
Someone manually edits a deployment in the cluster,

381
00:13:03,640 --> 00:13:06,240
maybe a junior engineer trying to fix something quickly.

382
00:13:06,240 --> 00:13:08,960
The operator detects the drift on the next reconciliation cycle

383
00:13:08,960 --> 00:13:09,720
and reverts it.

384
00:13:09,720 --> 00:13:11,640
The cluster heals itself, and you don't even know it

385
00:13:11,640 --> 00:13:13,360
happened unless you check the logs.

386
00:13:13,360 --> 00:13:15,840
Consistency across environments becomes automatic.

387
00:13:15,840 --> 00:13:18,200
Dev, test, staging, production, they all pull

388
00:13:18,200 --> 00:13:20,920
from the same Git repo, different branches or folders,

389
00:13:20,920 --> 00:13:22,360
but the same source of truth.

390
00:13:22,360 --> 00:13:25,000
No more it works on my machine because your staging cluster

391
00:13:25,000 --> 00:13:27,040
drifted away from production weeks ago.

392
00:13:27,040 --> 00:13:29,200
Security improves because the cluster pulls from Git

393
00:13:29,200 --> 00:13:30,560
instead of being pushed to.

394
00:13:30,560 --> 00:13:33,240
Your CI pipeline never holds credentials that give it direct access

395
00:13:33,240 --> 00:13:33,840
to production.

396
00:13:33,840 --> 00:13:35,400
If someone compromises the pipeline,

397
00:13:35,400 --> 00:13:37,080
they can't touch the cluster.

398
00:13:37,080 --> 00:13:39,240
The operator decides what gets applied and when.

399
00:13:39,240 --> 00:13:40,480
Least privileged by design.

400
00:13:40,480 --> 00:13:42,160
There's data backing this up too.

401
00:13:42,160 --> 00:13:44,760
According to Dora Research, teams that adopt GitHub's

402
00:13:44,760 --> 00:13:47,480
see about a 25% drop in deployment errors

403
00:13:47,480 --> 00:13:49,800
and mean time to recovery drops to under two minutes

404
00:13:49,800 --> 00:13:51,440
in well-implemented setups.

405
00:13:51,440 --> 00:13:52,560
That's not theory.

406
00:13:52,560 --> 00:13:54,280
That's what organizations are reporting.

407
00:13:54,280 --> 00:13:56,920
And there's a collaboration benefit that's easy to overlook.

408
00:13:56,920 --> 00:13:59,920
Infrastructure changes go through pull requests, code reviews,

409
00:13:59,920 --> 00:14:01,200
and automated tests.

410
00:14:01,200 --> 00:14:03,240
Exactly the same as application code.

411
00:14:03,240 --> 00:14:05,680
Your ops team and your dev team speak the same language.

412
00:14:05,680 --> 00:14:08,600
Git, no more handoffs, no more, just deploy this for me.

413
00:14:08,600 --> 00:14:10,080
Everyone works the same way.

414
00:14:10,080 --> 00:14:11,840
But there are still some common misunderstandings

415
00:14:11,840 --> 00:14:14,080
worth clearing up.

416
00:14:14,080 --> 00:14:15,880
Common myths and getting started.

417
00:14:15,880 --> 00:14:18,360
Let's start by clearing up some common myths about GitOps.

418
00:14:18,360 --> 00:14:21,320
First up, many people think GitOps is only for Kubernetes

419
00:14:21,320 --> 00:14:23,080
and sure it works best on Kubernetes.

420
00:14:23,080 --> 00:14:24,000
No question there.

421
00:14:24,000 --> 00:14:26,040
Kubernetes is built around declarative state

422
00:14:26,040 --> 00:14:28,320
and reconciliation, so it's a natural fit.

423
00:14:28,320 --> 00:14:30,720
But here's the thing, those same principles apply

424
00:14:30,720 --> 00:14:32,800
anywhere you have declarative configurations.

425
00:14:32,800 --> 00:14:34,360
You can use GitOps with terraform,

426
00:14:34,360 --> 00:14:37,400
poloomy, even Ansible, just store those configs in Git

427
00:14:37,400 --> 00:14:38,960
and have a pipeline apply them.

428
00:14:38,960 --> 00:14:41,520
The self-healing part is harder outside Kubernetes,

429
00:14:41,520 --> 00:14:44,120
but the source of truth discipline works everywhere.

430
00:14:44,120 --> 00:14:45,920
Another myth is that you absolutely need

431
00:14:45,920 --> 00:14:48,240
RGO CD or flux to do GitOps.

432
00:14:48,240 --> 00:14:50,400
If you want the full model, pull-based deployment

433
00:14:50,400 --> 00:14:52,840
continuous reconciliation, drift detection,

434
00:14:52,840 --> 00:14:55,200
then yes, you need some kind of GitOps operator.

435
00:14:55,200 --> 00:14:56,440
But you can start much simpler.

436
00:14:56,440 --> 00:14:58,040
Just put all your manifests in Git

437
00:14:58,040 --> 00:14:59,720
and use pull requests for changes.

438
00:14:59,720 --> 00:15:01,400
That alone gives you most of the ordered

439
00:15:01,400 --> 00:15:02,720
and collaboration benefits.

440
00:15:02,720 --> 00:15:04,320
You can always add an operator later

441
00:15:04,320 --> 00:15:05,920
when you need the automation.

442
00:15:05,920 --> 00:15:07,960
And finally, there's the myth that GitOps replaces

443
00:15:07,960 --> 00:15:09,280
CI/CD entirely.

444
00:15:09,280 --> 00:15:09,960
It doesn't.

445
00:15:09,960 --> 00:15:11,200
It replaces the CD part.

446
00:15:11,200 --> 00:15:14,560
CI still builds your code, runs tests, scans for vulnerabilities,

447
00:15:14,560 --> 00:15:16,880
and pushes container images to a registry.

448
00:15:16,880 --> 00:15:18,120
That all stays the same.

449
00:15:18,120 --> 00:15:20,400
What changes is how those images get deployed.

450
00:15:20,400 --> 00:15:23,160
Instead of the CI pipeline pushing them into the cluster,

451
00:15:23,160 --> 00:15:25,960
the GitOps operator pulls the updated manifests from Git.

452
00:15:25,960 --> 00:15:28,840
So CI and GitOps work together, not instead of each other.

453
00:15:28,840 --> 00:15:30,400
Getting started is actually straightforward.

454
00:15:30,400 --> 00:15:33,960
Pick a small AKS cluster and enable flux through the Azure portal.

455
00:15:33,960 --> 00:15:35,560
It takes just a few clicks.

456
00:15:35,560 --> 00:15:37,480
Then point it at a Git repository

457
00:15:37,480 --> 00:15:40,520
that contains a simple deployment IAML, watch it sync,

458
00:15:40,520 --> 00:15:42,040
and you're off to the races.

459
00:15:42,040 --> 00:15:43,960
Try changing a value in the IAML, commit it,

460
00:15:43,960 --> 00:15:45,120
and watch the cluster update.

461
00:15:45,120 --> 00:15:46,560
That's your first GitHub workflow.

462
00:15:46,560 --> 00:15:49,280
From there, you can add environments, learn customized,

463
00:15:49,280 --> 00:15:52,440
since flux uses it heavily, and setup automated image updates

464
00:15:52,440 --> 00:15:54,920
with tools like renovate or dependable.

465
00:15:54,920 --> 00:15:56,400
So that's GitOps in a nutshell.

466
00:15:56,400 --> 00:15:59,080
It turns your infrastructure into a Git repository,

467
00:15:59,080 --> 00:16:02,520
making everything traceable, revertible, and self-healing.

468
00:16:02,520 --> 00:16:04,080
If you manage Kubernetes on Azure,

469
00:16:04,080 --> 00:16:06,440
go try the GitOps integration in AKS today.

470
00:16:06,440 --> 00:16:08,440
It takes 10 minutes to setup and will change

471
00:16:08,440 --> 00:16:09,760
how you think about deployments.

472
00:16:09,760 --> 00:16:11,760
Subscribe for more plain English explanations

473
00:16:11,760 --> 00:16:13,840
of Microsoft's cloud tools.

