4914 lines
265 KiB
HTML
4914 lines
265 KiB
HTML
|
|
<!doctype html>
|
|
<html lang="en" class="no-js">
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
|
|
<meta name="description" content="Documentation for the GitOps-managed Kubernetes cluster">
|
|
|
|
|
|
|
|
|
|
<link rel="prev" href="../GITOPS-ARCHITECTURE/">
|
|
|
|
|
|
<link rel="next" href="../OPERATIONS-RUNBOOK/">
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="icon" href="../assets/images/favicon.png">
|
|
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
|
|
|
|
|
|
|
|
<title>Developer Guide - K8s Launchpad</title>
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../assets/stylesheets/palette.ab4e12ef.min.css">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
|
|
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
|
|
|
|
|
|
|
|
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
|
|
|
|
|
|
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
|
|
|
|
|
|
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
|
|
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
|
|
<label class="md-overlay" for="__drawer"></label>
|
|
<div data-md-component="skip">
|
|
|
|
|
|
<a href="#developer-onboarding-guide" class="md-skip">
|
|
Skip to content
|
|
</a>
|
|
|
|
</div>
|
|
<div data-md-component="announce">
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<header class="md-header md-header--shadow" data-md-component="header">
|
|
<nav class="md-header__inner md-grid" aria-label="Header">
|
|
<a href=".." title="K8s Launchpad" class="md-header__button md-logo" aria-label="K8s Launchpad" data-md-component="logo">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
|
|
|
|
</a>
|
|
<label class="md-header__button md-icon" for="__drawer">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
|
|
</label>
|
|
<div class="md-header__title" data-md-component="header-title">
|
|
<div class="md-header__ellipsis">
|
|
<div class="md-header__topic">
|
|
<span class="md-ellipsis">
|
|
K8s Launchpad
|
|
</span>
|
|
</div>
|
|
<div class="md-header__topic" data-md-component="header-topic">
|
|
<span class="md-ellipsis">
|
|
|
|
Developer Guide
|
|
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<form class="md-header__option" data-md-component="palette">
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
|
|
|
|
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
|
|
</label>
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
|
|
|
|
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
|
|
</label>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-header__button md-icon" for="__search">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
|
</label>
|
|
<div class="md-search" data-md-component="search" role="dialog">
|
|
<label class="md-search__overlay" for="__search"></label>
|
|
<div class="md-search__inner" role="search">
|
|
<form class="md-search__form" name="search">
|
|
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
|
|
<label class="md-search__icon md-icon" for="__search">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
|
|
</label>
|
|
<nav class="md-search__options" aria-label="Search">
|
|
|
|
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
|
</button>
|
|
</nav>
|
|
|
|
</form>
|
|
<div class="md-search__output">
|
|
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
|
|
<div class="md-search-result" data-md-component="search-result">
|
|
<div class="md-search-result__meta">
|
|
Initializing search
|
|
</div>
|
|
<ol class="md-search-result__list" role="presentation"></ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="md-header__source">
|
|
<a href="https://git.forteapps.net/Forte/launchpad" title="Go to repository" class="md-source" data-md-component="source">
|
|
<div class="md-source__icon md-icon">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
|
</div>
|
|
<div class="md-source__repository">
|
|
Forte/launchpad
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
</header>
|
|
|
|
<div class="md-container" data-md-component="container">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<main class="md-main" data-md-component="main">
|
|
<div class="md-main__inner md-grid">
|
|
|
|
|
|
|
|
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
|
|
<div class="md-sidebar__scrollwrap">
|
|
<div class="md-sidebar__inner">
|
|
|
|
|
|
|
|
|
|
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
|
|
<label class="md-nav__title" for="__drawer">
|
|
<a href=".." title="K8s Launchpad" class="md-nav__button md-logo" aria-label="K8s Launchpad" data-md-component="logo">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
|
|
|
|
</a>
|
|
K8s Launchpad
|
|
</label>
|
|
|
|
<div class="md-nav__source">
|
|
<a href="https://git.forteapps.net/Forte/launchpad" title="Go to repository" class="md-source" data-md-component="source">
|
|
<div class="md-source__icon md-icon">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
|
</div>
|
|
<div class="md-source__repository">
|
|
Forte/launchpad
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href=".." class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Home
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../GITOPS-ARCHITECTURE/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
GitOps Architecture
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--active">
|
|
|
|
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-nav__link md-nav__link--active" for="__toc">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Developer Guide
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<a href="./" class="md-nav__link md-nav__link--active">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Developer Guide
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-nav__title" for="__toc">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
Table of contents
|
|
</label>
|
|
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#table-of-contents" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Table of Contents
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#getting-started" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Getting Started
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Getting Started">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#what-youll-learn" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
What You'll Learn
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#who-this-guide-is-for" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Who This Guide Is For
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#prerequisites" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Prerequisites
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Prerequisites">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#required-knowledge" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Required Knowledge
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#required-tools" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Required Tools
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-access" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository Access
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#cluster-access-if-needed" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Cluster Access (If Needed)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#local-development-setup" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Local Development Setup
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Local Development Setup">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#1-clone-the-repositories" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
1. Clone the Repositories
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#2-local-development-environment" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
2. Local Development Environment
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#3-understanding-the-deployment-flow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
3. Understanding the Deployment Flow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#understanding-the-workflow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Understanding the Workflow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Understanding the Workflow">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#three-repository-pattern" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Three-Repository Pattern
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-deploying-myapp" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example: Deploying "myapp"
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Example: Deploying "myapp"">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-forte-helm-chart-templates" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository: forte-helm (Chart Templates)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-helm-values-your-app-config" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository: helm-values (Your App Config)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-launchpad-argocd-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository: launchpad (ArgoCD Application)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#deploying-your-first-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Deploying Your First Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Deploying Your First Application">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#scenario-youve-built-a-new-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Scenario: You've Built a New Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-prepare-your-application-repository" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Prepare Your Application Repository
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-create-helm-values" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Create Helm Values
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-create-argocd-application-manifest" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Create ArgoCD Application Manifest
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-4-verify-deployment" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 4: Verify Deployment
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-5-access-your-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 5: Access Your Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#updating-an-existing-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Updating an Existing Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Updating an Existing Application">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#scenario-deploying-a-code-change" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Scenario: Deploying a Code Change
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#method-1-automatic-recommended" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Method 1: Automatic (Recommended)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#method-2-manual-image-tag-update" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Method 2: Manual Image Tag Update
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#method-3-configuration-changes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Method 3: Configuration Changes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#method-4-application-manifest-changes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Method 4: Application Manifest Changes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#working-with-secrets" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Working with Secrets
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Working with Secrets">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#understanding-secret-management" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Understanding Secret Management
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#creating-a-new-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Creating a New Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Creating a New Secret">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-create-plain-secret-locally" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Create Plain Secret Locally
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-seal-the-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Seal the Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-commit-sealed-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Commit Sealed Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-4-reference-secret-in-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 4: Reference Secret in Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#updating-a-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Updating a Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#secret-best-practices" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Secret Best Practices
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#where-secrets-are-stored" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Where Secrets Are Stored
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#enabling-authentication-for-applications" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Enabling Authentication for Applications
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Enabling Authentication for Applications">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#how-it-works" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
How It Works
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#authentication-modes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Authentication Modes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#token-based-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Token-Based Authentication
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Token-Based Authentication">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-configure-helm-values" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Configure Helm Values
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-generate-token-if-needed" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Generate Token (if needed)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-deploy-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Deploy Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-4-access-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 4: Access Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#advanced-custom-secret-name" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Advanced: Custom Secret Name
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#oidc-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
OIDC Authentication
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="OIDC Authentication">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-configure-identity-provider" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Configure Identity Provider
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-create-oidc-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Create OIDC Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-configure-helm-values" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Configure Helm Values
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-4-deploy-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 4: Deploy Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-5-access-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 5: Access Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#authentication-configuration-reference" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Authentication Configuration Reference
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Authentication Configuration Reference">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#helm-values-schema" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Helm Values Schema
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#annotations-set-by-helm-chart" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Annotations Set by Helm Chart
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#sidecar-configuration" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Sidecar Configuration
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#advanced-custom-sidecar-image" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Advanced: Custom Sidecar Image
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#authentication-examples" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Authentication Examples
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Authentication Examples">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-1-internal-api-with-token-auth" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example 1: Internal API with Token Auth
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-2-user-facing-app-with-oidc" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example 2: User-Facing App with OIDC
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-3-mcp-server-with-oauth-20" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example 3: MCP Server with OAuth 2.0
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-4-disabling-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example 4: Disabling Authentication
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#troubleshooting-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Troubleshooting Authentication
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Troubleshooting Authentication">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#issue-401-unauthorized-token-mode" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Issue: 401 Unauthorized (Token Mode)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#issue-oidc-login-loop" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Issue: OIDC Login Loop
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#issue-auth-sidecar-not-injected" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Issue: Auth Sidecar Not Injected
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#issue-auth-sidecar-crashes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Issue: Auth Sidecar Crashes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#authentication-best-practices" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Authentication Best Practices
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#adding-a-new-keycloak-client" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Adding a New Keycloak Client
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Adding a New Keycloak Client">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#self-service-oidc-client-registration" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Self-Service OIDC Client Registration
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Self-Service OIDC Client Registration">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#how-it-works_1" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
How It Works
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-create-the-config-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Create the Config Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-reference-the-credential-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Reference the Credential Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-deploy-and-wait" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Deploy and Wait
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#change-detection" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Change Detection
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#legacy-method-realm-json" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Legacy Method: Realm JSON
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Legacy Method: Realm JSON">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-add-client-to-realm-config" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Add Client to Realm Config
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-reference-the-secret-in-your-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Reference the Secret in Your Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-commit-and-push" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Commit and Push
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#legacy-sync-attribute-reference" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Legacy Sync Attribute Reference
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#retrieving-secrets-for-external-deployments" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Retrieving Secrets for External Deployments
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#registrar-behavior-notes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Registrar Behavior Notes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#troubleshooting" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Troubleshooting
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Troubleshooting">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#application-not-deploying" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Application Not Deploying
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Application Not Deploying">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-application-stuck-in-syncing-state" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Application stuck in "Syncing" state
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-pods-crashing-crashloopbackoff" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Pods crashing (CrashLoopBackOff)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-application-not-accessible-via-domain" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Application not accessible via domain
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#secret-issues" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Secret Issues
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Secret Issues">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-secret-not-found" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Secret not found
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-secret-exists-but-pods-cant-access-it" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Secret exists but pods can't access it
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#sync-failures" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Sync Failures
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Sync Failures">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-argocd-shows-out-of-sync" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: ArgoCD shows "Out of Sync"
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-sync-succeeds-but-application-is-degraded" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Sync succeeds but application is "Degraded"
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#getting-help" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Getting Help
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#documentation" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Documentation
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Documentation">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#viewing-the-docs" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Viewing the Docs
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#editing-documentation" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Editing Documentation
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#local-preview" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Local Preview
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#how-it-works_2" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
How It Works
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#best-practices" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Best Practices
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Best Practices">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#development-workflow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Development Workflow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#configuration-management" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Configuration Management
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#secret-management" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Secret Management
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#git-workflow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Git Workflow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#quick-reference" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Quick Reference
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Quick Reference">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#common-commands" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Common Commands
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-locations" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository Locations
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#file-paths" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
File Paths
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#next-steps" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Next Steps
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../OPERATIONS-RUNBOOK/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Operations Runbook
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../REFERENCE/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Technical Reference
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
|
|
<div class="md-sidebar__scrollwrap">
|
|
<div class="md-sidebar__inner">
|
|
|
|
|
|
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-nav__title" for="__toc">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
Table of contents
|
|
</label>
|
|
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#table-of-contents" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Table of Contents
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#getting-started" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Getting Started
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Getting Started">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#what-youll-learn" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
What You'll Learn
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#who-this-guide-is-for" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Who This Guide Is For
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#prerequisites" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Prerequisites
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Prerequisites">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#required-knowledge" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Required Knowledge
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#required-tools" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Required Tools
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-access" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository Access
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#cluster-access-if-needed" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Cluster Access (If Needed)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#local-development-setup" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Local Development Setup
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Local Development Setup">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#1-clone-the-repositories" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
1. Clone the Repositories
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#2-local-development-environment" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
2. Local Development Environment
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#3-understanding-the-deployment-flow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
3. Understanding the Deployment Flow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#understanding-the-workflow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Understanding the Workflow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Understanding the Workflow">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#three-repository-pattern" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Three-Repository Pattern
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-deploying-myapp" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example: Deploying "myapp"
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Example: Deploying "myapp"">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-forte-helm-chart-templates" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository: forte-helm (Chart Templates)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-helm-values-your-app-config" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository: helm-values (Your App Config)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-launchpad-argocd-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository: launchpad (ArgoCD Application)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#deploying-your-first-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Deploying Your First Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Deploying Your First Application">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#scenario-youve-built-a-new-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Scenario: You've Built a New Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-prepare-your-application-repository" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Prepare Your Application Repository
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-create-helm-values" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Create Helm Values
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-create-argocd-application-manifest" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Create ArgoCD Application Manifest
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-4-verify-deployment" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 4: Verify Deployment
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-5-access-your-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 5: Access Your Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#updating-an-existing-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Updating an Existing Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Updating an Existing Application">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#scenario-deploying-a-code-change" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Scenario: Deploying a Code Change
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#method-1-automatic-recommended" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Method 1: Automatic (Recommended)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#method-2-manual-image-tag-update" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Method 2: Manual Image Tag Update
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#method-3-configuration-changes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Method 3: Configuration Changes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#method-4-application-manifest-changes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Method 4: Application Manifest Changes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#working-with-secrets" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Working with Secrets
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Working with Secrets">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#understanding-secret-management" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Understanding Secret Management
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#creating-a-new-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Creating a New Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Creating a New Secret">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-create-plain-secret-locally" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Create Plain Secret Locally
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-seal-the-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Seal the Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-commit-sealed-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Commit Sealed Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-4-reference-secret-in-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 4: Reference Secret in Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#updating-a-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Updating a Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#secret-best-practices" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Secret Best Practices
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#where-secrets-are-stored" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Where Secrets Are Stored
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#enabling-authentication-for-applications" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Enabling Authentication for Applications
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Enabling Authentication for Applications">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#how-it-works" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
How It Works
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#authentication-modes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Authentication Modes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#token-based-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Token-Based Authentication
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Token-Based Authentication">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-configure-helm-values" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Configure Helm Values
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-generate-token-if-needed" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Generate Token (if needed)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-deploy-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Deploy Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-4-access-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 4: Access Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#advanced-custom-secret-name" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Advanced: Custom Secret Name
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#oidc-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
OIDC Authentication
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="OIDC Authentication">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-configure-identity-provider" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Configure Identity Provider
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-create-oidc-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Create OIDC Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-configure-helm-values" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Configure Helm Values
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-4-deploy-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 4: Deploy Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-5-access-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 5: Access Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#authentication-configuration-reference" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Authentication Configuration Reference
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Authentication Configuration Reference">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#helm-values-schema" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Helm Values Schema
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#annotations-set-by-helm-chart" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Annotations Set by Helm Chart
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#sidecar-configuration" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Sidecar Configuration
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#advanced-custom-sidecar-image" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Advanced: Custom Sidecar Image
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#authentication-examples" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Authentication Examples
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Authentication Examples">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-1-internal-api-with-token-auth" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example 1: Internal API with Token Auth
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-2-user-facing-app-with-oidc" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example 2: User-Facing App with OIDC
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-3-mcp-server-with-oauth-20" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example 3: MCP Server with OAuth 2.0
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#example-4-disabling-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Example 4: Disabling Authentication
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#troubleshooting-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Troubleshooting Authentication
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Troubleshooting Authentication">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#issue-401-unauthorized-token-mode" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Issue: 401 Unauthorized (Token Mode)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#issue-oidc-login-loop" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Issue: OIDC Login Loop
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#issue-auth-sidecar-not-injected" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Issue: Auth Sidecar Not Injected
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#issue-auth-sidecar-crashes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Issue: Auth Sidecar Crashes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#authentication-best-practices" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Authentication Best Practices
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#adding-a-new-keycloak-client" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Adding a New Keycloak Client
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Adding a New Keycloak Client">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#self-service-oidc-client-registration" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Self-Service OIDC Client Registration
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Self-Service OIDC Client Registration">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#how-it-works_1" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
How It Works
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-create-the-config-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Create the Config Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-reference-the-credential-secret" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Reference the Credential Secret
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-deploy-and-wait" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Deploy and Wait
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#change-detection" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Change Detection
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#legacy-method-realm-json" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Legacy Method: Realm JSON
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Legacy Method: Realm JSON">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-1-add-client-to-realm-config" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 1: Add Client to Realm Config
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-2-reference-the-secret-in-your-application" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 2: Reference the Secret in Your Application
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#step-3-commit-and-push" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Step 3: Commit and Push
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#legacy-sync-attribute-reference" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Legacy Sync Attribute Reference
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#retrieving-secrets-for-external-deployments" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Retrieving Secrets for External Deployments
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#registrar-behavior-notes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Registrar Behavior Notes
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#troubleshooting" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Troubleshooting
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Troubleshooting">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#application-not-deploying" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Application Not Deploying
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Application Not Deploying">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-application-stuck-in-syncing-state" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Application stuck in "Syncing" state
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-pods-crashing-crashloopbackoff" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Pods crashing (CrashLoopBackOff)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-application-not-accessible-via-domain" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Application not accessible via domain
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#secret-issues" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Secret Issues
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Secret Issues">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-secret-not-found" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Secret not found
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-secret-exists-but-pods-cant-access-it" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Secret exists but pods can't access it
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#sync-failures" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Sync Failures
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Sync Failures">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-argocd-shows-out-of-sync" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: ArgoCD shows "Out of Sync"
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#problem-sync-succeeds-but-application-is-degraded" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Problem: Sync succeeds but application is "Degraded"
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#getting-help" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Getting Help
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#documentation" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Documentation
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Documentation">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#viewing-the-docs" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Viewing the Docs
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#editing-documentation" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Editing Documentation
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#local-preview" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Local Preview
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#how-it-works_2" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
How It Works
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#best-practices" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Best Practices
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Best Practices">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#development-workflow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Development Workflow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#configuration-management" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Configuration Management
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#secret-management" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Secret Management
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#git-workflow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Git Workflow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#quick-reference" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Quick Reference
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Quick Reference">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#common-commands" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Common Commands
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#repository-locations" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Repository Locations
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#file-paths" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
File Paths
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#next-steps" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Next Steps
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="md-content" data-md-component="content">
|
|
|
|
<article class="md-content__inner md-typeset">
|
|
|
|
|
|
|
|
|
|
|
|
<h1 id="developer-onboarding-guide">Developer Onboarding Guide<a class="headerlink" href="#developer-onboarding-guide" title="Permanent link">¶</a></h1>
|
|
<h2 id="table-of-contents">Table of Contents<a class="headerlink" href="#table-of-contents" title="Permanent link">¶</a></h2>
|
|
<ul>
|
|
<li><a href="#getting-started">Getting Started</a></li>
|
|
<li><a href="#prerequisites">Prerequisites</a></li>
|
|
<li><a href="#local-development-setup">Local Development Setup</a></li>
|
|
<li><a href="#understanding-the-workflow">Understanding the Workflow</a></li>
|
|
<li><a href="#deploying-your-first-application">Deploying Your First Application</a></li>
|
|
<li><a href="#updating-an-existing-application">Updating an Existing Application</a></li>
|
|
<li><a href="#working-with-secrets">Working with Secrets</a></li>
|
|
<li><a href="#enabling-authentication-for-applications">Enabling Authentication for Applications</a></li>
|
|
<li><a href="#adding-a-new-keycloak-client">Adding a New Keycloak Client</a></li>
|
|
<li><a href="#troubleshooting">Troubleshooting</a></li>
|
|
<li><a href="#documentation">Documentation</a></li>
|
|
<li><a href="#best-practices">Best Practices</a></li>
|
|
</ul>
|
|
<hr />
|
|
<h2 id="getting-started">Getting Started<a class="headerlink" href="#getting-started" title="Permanent link">¶</a></h2>
|
|
<p>Welcome! This guide will help you understand how to develop and deploy applications on our Kubernetes cluster using GitOps principles powered by ArgoCD.</p>
|
|
<h3 id="what-youll-learn">What You'll Learn<a class="headerlink" href="#what-youll-learn" title="Permanent link">¶</a></h3>
|
|
<ul>
|
|
<li>How our GitOps architecture works</li>
|
|
<li>How to deploy a new application</li>
|
|
<li>How to update existing applications</li>
|
|
<li>How to manage secrets securely</li>
|
|
<li>Common troubleshooting techniques</li>
|
|
</ul>
|
|
<h3 id="who-this-guide-is-for">Who This Guide Is For<a class="headerlink" href="#who-this-guide-is-for" title="Permanent link">¶</a></h3>
|
|
<ul>
|
|
<li>Developers deploying new applications</li>
|
|
<li>Developers maintaining existing applications</li>
|
|
<li>Team members who need to understand the deployment process</li>
|
|
</ul>
|
|
<hr />
|
|
<h2 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link">¶</a></h2>
|
|
<h3 id="required-knowledge">Required Knowledge<a class="headerlink" href="#required-knowledge" title="Permanent link">¶</a></h3>
|
|
<ul>
|
|
<li>✅ Basic Git workflow (clone, commit, push, pull)</li>
|
|
<li>✅ Docker basics (Dockerfile, building images)</li>
|
|
<li>✅ YAML syntax</li>
|
|
<li>✅ Basic understanding of Kubernetes concepts (pods, deployments, services)</li>
|
|
<li>⚠️ Helm knowledge (helpful but not required - templates are provided)</li>
|
|
</ul>
|
|
<h3 id="required-tools">Required Tools<a class="headerlink" href="#required-tools" title="Permanent link">¶</a></h3>
|
|
<p>Most developers <strong>do NOT need kubectl access</strong> to the cluster. You'll primarily work with Git repositories.</p>
|
|
<p>If you do need cluster access, install:</p>
|
|
<ol>
|
|
<li>
|
|
<p><strong>kubectl</strong> - Kubernetes CLI
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># macOS</span>
|
|
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>brew<span class="w"> </span>install<span class="w"> </span>kubectl
|
|
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>
|
|
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a><span class="c1"># Windows</span>
|
|
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>choco<span class="w"> </span>install<span class="w"> </span>kubernetes-cli
|
|
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>
|
|
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a><span class="c1"># Linux</span>
|
|
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>curl<span class="w"> </span>-LO<span class="w"> </span><span class="s2">"https://dl.k8s.io/release/</span><span class="k">$(</span>curl<span class="w"> </span>-L<span class="w"> </span>-s<span class="w"> </span>https://dl.k8s.io/release/stable.txt<span class="k">)</span><span class="s2">/bin/linux/amd64/kubectl"</span>
|
|
</code></pre></div></p>
|
|
</li>
|
|
<li>
|
|
<p><strong>kubeseal</strong> - For sealing secrets
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="c1"># macOS</span>
|
|
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>brew<span class="w"> </span>install<span class="w"> </span>kubeseal
|
|
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a>
|
|
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="c1"># Windows</span>
|
|
<a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a>choco<span class="w"> </span>install<span class="w"> </span>kubeseal
|
|
<a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a>
|
|
<a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a><span class="c1"># Linux</span>
|
|
<a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a>wget<span class="w"> </span>https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/kubeseal-0.24.0-linux-amd64.tar.gz
|
|
<a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a>tar<span class="w"> </span>-xvzf<span class="w"> </span>kubeseal-0.24.0-linux-amd64.tar.gz
|
|
<a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a>sudo<span class="w"> </span>mv<span class="w"> </span>kubeseal<span class="w"> </span>/usr/local/bin/
|
|
</code></pre></div></p>
|
|
</li>
|
|
<li>
|
|
<p><strong>Git</strong> - Version control
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>git<span class="w"> </span>--version<span class="w"> </span><span class="c1"># Should already be installed</span>
|
|
</code></pre></div></p>
|
|
</li>
|
|
<li>
|
|
<p><strong>Docker</strong> - For local development
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="c1"># macOS/Windows: Install Docker Desktop</span>
|
|
<a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="c1"># Linux: Install Docker Engine</span>
|
|
<a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a>docker<span class="w"> </span>--version
|
|
</code></pre></div></p>
|
|
</li>
|
|
</ol>
|
|
<h3 id="repository-access">Repository Access<a class="headerlink" href="#repository-access" title="Permanent link">¶</a></h3>
|
|
<p>You'll need read/write access to these repositories:</p>
|
|
<ol>
|
|
<li>
|
|
<p><strong>launchpad</strong> (Config repo)
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>git<span class="w"> </span>clone<span class="w"> </span>https://git.forteapps.net/Forte/launchpad.git
|
|
<a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="nb">cd</span><span class="w"> </span>launchpad
|
|
</code></pre></div></p>
|
|
</li>
|
|
<li>
|
|
<p><strong>helm-values</strong> (Values repo)
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>git<span class="w"> </span>clone<span class="w"> </span>https://git.forteapps.net/Forte/helm-prod-values.git
|
|
<a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="nb">cd</span><span class="w"> </span>helm-values
|
|
</code></pre></div></p>
|
|
</li>
|
|
<li>
|
|
<p><strong>forte-helm</strong> (Chart repo - read-only for most developers)
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>git<span class="w"> </span>clone<span class="w"> </span>https://git.forteapps.net/Forte/forte-helm.git
|
|
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="nb">cd</span><span class="w"> </span>forte-helm
|
|
</code></pre></div></p>
|
|
</li>
|
|
</ol>
|
|
<h3 id="cluster-access-if-needed">Cluster Access (If Needed)<a class="headerlink" href="#cluster-access-if-needed" title="Permanent link">¶</a></h3>
|
|
<p>If you need kubectl access, ask the platform team for:
|
|
- Kubeconfig file
|
|
- Cluster context setup instructions</p>
|
|
<p>Save to <code>~/.kube/config</code> and verify:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>kubectl<span class="w"> </span>cluster-info
|
|
<a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>nodes
|
|
</code></pre></div></p>
|
|
<hr />
|
|
<h2 id="local-development-setup">Local Development Setup<a class="headerlink" href="#local-development-setup" title="Permanent link">¶</a></h2>
|
|
<h3 id="1-clone-the-repositories">1. Clone the Repositories<a class="headerlink" href="#1-clone-the-repositories" title="Permanent link">¶</a></h3>
|
|
<p>Set up a consistent folder structure:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>mkdir<span class="w"> </span>-p<span class="w"> </span>~/dev/k8s
|
|
<a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s
|
|
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a>
|
|
<a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a><span class="c1"># Clone repositories</span>
|
|
<a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a>git<span class="w"> </span>clone<span class="w"> </span>https://git.forteapps.net/Forte/launchpad.git<span class="w"> </span>launchpad
|
|
<a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a>git<span class="w"> </span>clone<span class="w"> </span>https://git.forteapps.net/Forte/helm-prod-values<span class="w"> </span>helm-prod-values
|
|
<a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a>git<span class="w"> </span>clone<span class="w"> </span>https://git.forteapps.net/Forte/forte-helm<span class="w"> </span>forte-helm
|
|
<a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a>
|
|
<a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a><span class="c1"># Your folder structure:</span>
|
|
<a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a><span class="c1"># ~/dev/k8s/</span>
|
|
<a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a><span class="c1"># ├── launchpad/ (Config repo)</span>
|
|
<a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a><span class="c1"># ├── helm-prod-values/ (Values repo)</span>
|
|
<a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a><span class="c1"># └── forte-helm/ (Chart repo)</span>
|
|
</code></pre></div>
|
|
<h3 id="2-local-development-environment">2. Local Development Environment<a class="headerlink" href="#2-local-development-environment" title="Permanent link">¶</a></h3>
|
|
<p>Most applications use <strong>Docker Compose</strong> for local development:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="c1"># In your application repository</span>
|
|
<a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>docker-compose<span class="w"> </span>up
|
|
<a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a>
|
|
<a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a><span class="c1"># Or for frontend applications</span>
|
|
<a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a>npm<span class="w"> </span>install
|
|
<a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a>npm<span class="w"> </span>run<span class="w"> </span>dev
|
|
</code></pre></div>
|
|
<p><strong>You DO NOT run applications locally on Kubernetes.</strong> Use Docker Compose or native tooling (npm, python, etc.).</p>
|
|
<h3 id="3-understanding-the-deployment-flow">3. Understanding the Deployment Flow<a class="headerlink" href="#3-understanding-the-deployment-flow" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a>┌─────────────────────────────────────────────────────────────────┐
|
|
<a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>│ Step 1: Develop Locally │
|
|
<a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a>│ - Write code in your application repository │
|
|
<a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a>│ - Test with Docker Compose or npm/python/etc. │
|
|
<a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a>│ - Build Docker image │
|
|
<a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a>└─────────────────────────────────────────────────────────────────┘
|
|
<a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a> │
|
|
<a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a> ▼
|
|
<a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a>┌─────────────────────────────────────────────────────────────────┐
|
|
<a id="__codelineno-10-10" name="__codelineno-10-10" href="#__codelineno-10-10"></a>│ Step 2: CI/CD Pipeline (Automated) │
|
|
<a id="__codelineno-10-11" name="__codelineno-10-11" href="#__codelineno-10-11"></a>│ - GitHub Actions builds image │
|
|
<a id="__codelineno-10-12" name="__codelineno-10-12" href="#__codelineno-10-12"></a>│ - Pushes to container registry (GHCR, Docker Hub) │
|
|
<a id="__codelineno-10-13" name="__codelineno-10-13" href="#__codelineno-10-13"></a>│ - Tags with version (e.g., v2.0.4) │
|
|
<a id="__codelineno-10-14" name="__codelineno-10-14" href="#__codelineno-10-14"></a>│ - Updates helm-values repository with new tag │
|
|
<a id="__codelineno-10-15" name="__codelineno-10-15" href="#__codelineno-10-15"></a>└─────────────────────────────────────────────────────────────────┘
|
|
<a id="__codelineno-10-16" name="__codelineno-10-16" href="#__codelineno-10-16"></a> │
|
|
<a id="__codelineno-10-17" name="__codelineno-10-17" href="#__codelineno-10-17"></a> ▼
|
|
<a id="__codelineno-10-18" name="__codelineno-10-18" href="#__codelineno-10-18"></a>┌─────────────────────────────────────────────────────────────────┐
|
|
<a id="__codelineno-10-19" name="__codelineno-10-19" href="#__codelineno-10-19"></a>│ Step 3: GitOps Sync (Automated) │
|
|
<a id="__codelineno-10-20" name="__codelineno-10-20" href="#__codelineno-10-20"></a>│ - ArgoCD detects change in helm-values │
|
|
<a id="__codelineno-10-21" name="__codelineno-10-21" href="#__codelineno-10-21"></a>│ - Pulls updated configuration │
|
|
<a id="__codelineno-10-22" name="__codelineno-10-22" href="#__codelineno-10-22"></a>│ - Syncs to Kubernetes cluster │
|
|
<a id="__codelineno-10-23" name="__codelineno-10-23" href="#__codelineno-10-23"></a>│ - Sends Slack notification on success/failure │
|
|
<a id="__codelineno-10-24" name="__codelineno-10-24" href="#__codelineno-10-24"></a>└─────────────────────────────────────────────────────────────────┘
|
|
</code></pre></div>
|
|
<p><strong>Key Insight</strong>: You don't deploy directly. You push code, CI/CD builds it, and ArgoCD deploys it.</p>
|
|
<hr />
|
|
<h2 id="understanding-the-workflow">Understanding the Workflow<a class="headerlink" href="#understanding-the-workflow" title="Permanent link">¶</a></h2>
|
|
<h3 id="three-repository-pattern">Three-Repository Pattern<a class="headerlink" href="#three-repository-pattern" title="Permanent link">¶</a></h3>
|
|
<p>Our setup uses three repositories:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Repository</th>
|
|
<th>Purpose</th>
|
|
<th>Who Edits</th>
|
|
<th>How Often</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>forte-helm</strong></td>
|
|
<td>Helm chart templates (generic, reusable)</td>
|
|
<td>Platform engineers</td>
|
|
<td>❌ Rarely</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>helm-values</strong></td>
|
|
<td>Application configuration (image tag, env vars)</td>
|
|
<td>Developers / CI pipelines</td>
|
|
<td>✅ Sometimes</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>launchpad</strong></td>
|
|
<td>ArgoCD Applications (what gets deployed)</td>
|
|
<td>Platform / DevOps engineers</td>
|
|
<td>✅ Per new app</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="example-deploying-myapp">Example: Deploying "myapp"<a class="headerlink" href="#example-deploying-myapp" title="Permanent link">¶</a></h3>
|
|
<h4 id="repository-forte-helm-chart-templates">Repository: <code>forte-helm</code> (Chart Templates)<a class="headerlink" href="#repository-forte-helm-chart-templates" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="c1"># forteapp/templates/deployment.yaml</span>
|
|
<a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a><span class="c1"># Generic template used by ALL apps</span>
|
|
<a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">apps/v1</span>
|
|
<a id="__codelineno-11-4" name="__codelineno-11-4" href="#__codelineno-11-4"></a><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Deployment</span>
|
|
<a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a><span class="nt">metadata</span><span class="p">:</span>
|
|
<a id="__codelineno-11-6" name="__codelineno-11-6" href="#__codelineno-11-6"></a><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">{{</span><span class="w"> </span><span class="nv">.Values.app.name</span><span class="w"> </span><span class="p p-Indicator">}}</span>
|
|
<a id="__codelineno-11-7" name="__codelineno-11-7" href="#__codelineno-11-7"></a><span class="nt">spec</span><span class="p">:</span>
|
|
<a id="__codelineno-11-8" name="__codelineno-11-8" href="#__codelineno-11-8"></a><span class="w"> </span><span class="nt">containers</span><span class="p">:</span>
|
|
<a id="__codelineno-11-9" name="__codelineno-11-9" href="#__codelineno-11-9"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">app</span>
|
|
<a id="__codelineno-11-10" name="__codelineno-11-10" href="#__codelineno-11-10"></a><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="s">"{{</span><span class="nv"> </span><span class="s">.Values.app.image.repository</span><span class="nv"> </span><span class="s">}}:{{</span><span class="nv"> </span><span class="s">.Values.app.image.tag</span><span class="nv"> </span><span class="s">}}"</span>
|
|
<a id="__codelineno-11-11" name="__codelineno-11-11" href="#__codelineno-11-11"></a><span class="w"> </span><span class="nt">env</span><span class="p">:</span>
|
|
<a id="__codelineno-11-12" name="__codelineno-11-12" href="#__codelineno-11-12"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">PORT</span>
|
|
<a id="__codelineno-11-13" name="__codelineno-11-13" href="#__codelineno-11-13"></a><span class="w"> </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">{{</span><span class="w"> </span><span class="nv">.Values.app.port</span><span class="w"> </span><span class="p p-Indicator">}}</span>
|
|
</code></pre></div>
|
|
<h4 id="repository-helm-values-your-app-config">Repository: <code>helm-values</code> (Your App Config)<a class="headerlink" href="#repository-helm-values-your-app-config" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="c1"># myapp/values.yaml</span>
|
|
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="c1"># Your app's specific configuration</span>
|
|
<a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a><span class="nt">app</span><span class="p">:</span>
|
|
<a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a><span class="w"> </span><span class="nt">image</span><span class="p">:</span>
|
|
<a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a><span class="w"> </span><span class="nt">repository</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">ghcr.io/fortedigital/myapp</span>
|
|
<a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a><span class="w"> </span><span class="nt">tag</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1.0.0</span><span class="w"> </span><span class="c1"># CI/CD updates this</span>
|
|
<a id="__codelineno-12-7" name="__codelineno-12-7" href="#__codelineno-12-7"></a><span class="w"> </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3000</span>
|
|
<a id="__codelineno-12-8" name="__codelineno-12-8" href="#__codelineno-12-8"></a><span class="w"> </span><span class="nt">extraEnv</span><span class="p">:</span>
|
|
<a id="__codelineno-12-9" name="__codelineno-12-9" href="#__codelineno-12-9"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">API_URL</span>
|
|
<a id="__codelineno-12-10" name="__codelineno-12-10" href="#__codelineno-12-10"></a><span class="w"> </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://api.example.com</span>
|
|
</code></pre></div>
|
|
<h4 id="repository-launchpad-argocd-application">Repository: <code>launchpad</code> (ArgoCD Application)<a class="headerlink" href="#repository-launchpad-argocd-application" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="c1"># apps/myapp.yaml</span>
|
|
<a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a><span class="c1"># Tells ArgoCD to deploy your app</span>
|
|
<a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">argoproj.io/v1alpha1</span>
|
|
<a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Application</span>
|
|
<a id="__codelineno-13-5" name="__codelineno-13-5" href="#__codelineno-13-5"></a><span class="nt">metadata</span><span class="p">:</span>
|
|
<a id="__codelineno-13-6" name="__codelineno-13-6" href="#__codelineno-13-6"></a><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">myapp</span>
|
|
<a id="__codelineno-13-7" name="__codelineno-13-7" href="#__codelineno-13-7"></a><span class="w"> </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">argocd</span>
|
|
<a id="__codelineno-13-8" name="__codelineno-13-8" href="#__codelineno-13-8"></a><span class="nt">spec</span><span class="p">:</span>
|
|
<a id="__codelineno-13-9" name="__codelineno-13-9" href="#__codelineno-13-9"></a><span class="w"> </span><span class="nt">sources</span><span class="p">:</span>
|
|
<a id="__codelineno-13-10" name="__codelineno-13-10" href="#__codelineno-13-10"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">repoURL</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/fortedigital/forte-helm</span>
|
|
<a id="__codelineno-13-11" name="__codelineno-13-11" href="#__codelineno-13-11"></a><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">forteapp</span>
|
|
<a id="__codelineno-13-12" name="__codelineno-13-12" href="#__codelineno-13-12"></a><span class="w"> </span><span class="nt">helm</span><span class="p">:</span>
|
|
<a id="__codelineno-13-13" name="__codelineno-13-13" href="#__codelineno-13-13"></a><span class="w"> </span><span class="nt">valueFiles</span><span class="p">:</span>
|
|
<a id="__codelineno-13-14" name="__codelineno-13-14" href="#__codelineno-13-14"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">$values/myapp/values.yaml</span>
|
|
<a id="__codelineno-13-15" name="__codelineno-13-15" href="#__codelineno-13-15"></a>
|
|
<a id="__codelineno-13-16" name="__codelineno-13-16" href="#__codelineno-13-16"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">repoURL</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">git@github.com:fortedigital/helm-values.git</span>
|
|
<a id="__codelineno-13-17" name="__codelineno-13-17" href="#__codelineno-13-17"></a><span class="w"> </span><span class="nt">ref</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">values</span>
|
|
<a id="__codelineno-13-18" name="__codelineno-13-18" href="#__codelineno-13-18"></a>
|
|
<a id="__codelineno-13-19" name="__codelineno-13-19" href="#__codelineno-13-19"></a><span class="w"> </span><span class="nt">destination</span><span class="p">:</span>
|
|
<a id="__codelineno-13-20" name="__codelineno-13-20" href="#__codelineno-13-20"></a><span class="w"> </span><span class="nt">server</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://kubernetes.default.svc</span>
|
|
<a id="__codelineno-13-21" name="__codelineno-13-21" href="#__codelineno-13-21"></a><span class="w"> </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">myapp</span>
|
|
<a id="__codelineno-13-22" name="__codelineno-13-22" href="#__codelineno-13-22"></a>
|
|
<a id="__codelineno-13-23" name="__codelineno-13-23" href="#__codelineno-13-23"></a><span class="w"> </span><span class="nt">syncPolicy</span><span class="p">:</span>
|
|
<a id="__codelineno-13-24" name="__codelineno-13-24" href="#__codelineno-13-24"></a><span class="w"> </span><span class="nt">automated</span><span class="p">:</span>
|
|
<a id="__codelineno-13-25" name="__codelineno-13-25" href="#__codelineno-13-25"></a><span class="w"> </span><span class="nt">prune</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-13-26" name="__codelineno-13-26" href="#__codelineno-13-26"></a><span class="w"> </span><span class="nt">selfHeal</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-13-27" name="__codelineno-13-27" href="#__codelineno-13-27"></a><span class="w"> </span><span class="nt">syncOptions</span><span class="p">:</span>
|
|
<a id="__codelineno-13-28" name="__codelineno-13-28" href="#__codelineno-13-28"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">CreateNamespace=true</span>
|
|
</code></pre></div>
|
|
<hr />
|
|
<h2 id="deploying-your-first-application">Deploying Your First Application<a class="headerlink" href="#deploying-your-first-application" title="Permanent link">¶</a></h2>
|
|
<h3 id="scenario-youve-built-a-new-application">Scenario: You've Built a New Application<a class="headerlink" href="#scenario-youve-built-a-new-application" title="Permanent link">¶</a></h3>
|
|
<p>Let's deploy a new Node.js application called "hello-world".</p>
|
|
<h3 id="step-1-prepare-your-application-repository">Step 1: Prepare Your Application Repository<a class="headerlink" href="#step-1-prepare-your-application-repository" title="Permanent link">¶</a></h3>
|
|
<p>Ensure your app repository has:</p>
|
|
<ol>
|
|
<li>
|
|
<p><strong>Dockerfile</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="k">FROM</span><span class="w"> </span><span class="s">node:18-alpine</span>
|
|
<a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="k">WORKDIR</span><span class="w"> </span><span class="s">/app</span>
|
|
<a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="k">COPY</span><span class="w"> </span>package*.json<span class="w"> </span>./
|
|
<a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a><span class="k">RUN</span><span class="w"> </span>npm<span class="w"> </span>ci<span class="w"> </span>--only<span class="o">=</span>production
|
|
<a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a><span class="k">COPY</span><span class="w"> </span>.<span class="w"> </span>.
|
|
<a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a><span class="k">EXPOSE</span><span class="w"> </span><span class="s">3000</span>
|
|
<a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a><span class="k">CMD</span><span class="w"> </span><span class="p">[</span><span class="s2">"node"</span><span class="p">,</span><span class="w"> </span><span class="s2">"server.js"</span><span class="p">]</span>
|
|
</code></pre></div></p>
|
|
</li>
|
|
<li>
|
|
<p><strong>GitHub Actions Workflow</strong> (<code>.github/workflows/deploy.yml</code>)
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Build and Deploy</span>
|
|
<a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a>
|
|
<a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a><span class="nt">on</span><span class="p">:</span>
|
|
<a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="w"> </span><span class="nt">push</span><span class="p">:</span>
|
|
<a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a><span class="w"> </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="w"> </span><span class="nv">main</span><span class="w"> </span><span class="p p-Indicator">]</span>
|
|
<a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></a>
|
|
<a id="__codelineno-15-7" name="__codelineno-15-7" href="#__codelineno-15-7"></a><span class="nt">jobs</span><span class="p">:</span>
|
|
<a id="__codelineno-15-8" name="__codelineno-15-8" href="#__codelineno-15-8"></a><span class="w"> </span><span class="nt">build</span><span class="p">:</span>
|
|
<a id="__codelineno-15-9" name="__codelineno-15-9" href="#__codelineno-15-9"></a><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">ubuntu-latest</span>
|
|
<a id="__codelineno-15-10" name="__codelineno-15-10" href="#__codelineno-15-10"></a><span class="w"> </span><span class="nt">steps</span><span class="p">:</span>
|
|
<a id="__codelineno-15-11" name="__codelineno-15-11" href="#__codelineno-15-11"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">actions/checkout@v3</span>
|
|
<a id="__codelineno-15-12" name="__codelineno-15-12" href="#__codelineno-15-12"></a>
|
|
<a id="__codelineno-15-13" name="__codelineno-15-13" href="#__codelineno-15-13"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Set version</span>
|
|
<a id="__codelineno-15-14" name="__codelineno-15-14" href="#__codelineno-15-14"></a><span class="w"> </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">version</span>
|
|
<a id="__codelineno-15-15" name="__codelineno-15-15" href="#__codelineno-15-15"></a><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">echo "VERSION=v$(date +%Y%m%d-%H%M%S)" >> $GITHUB_OUTPUT</span>
|
|
<a id="__codelineno-15-16" name="__codelineno-15-16" href="#__codelineno-15-16"></a>
|
|
<a id="__codelineno-15-17" name="__codelineno-15-17" href="#__codelineno-15-17"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Build and push Docker image</span>
|
|
<a id="__codelineno-15-18" name="__codelineno-15-18" href="#__codelineno-15-18"></a><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">|</span>
|
|
<a id="__codelineno-15-19" name="__codelineno-15-19" href="#__codelineno-15-19"></a><span class="w"> </span><span class="no">echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin</span>
|
|
<a id="__codelineno-15-20" name="__codelineno-15-20" href="#__codelineno-15-20"></a><span class="w"> </span><span class="no">docker build -t ghcr.io/fortedigital/hello-world:${{ steps.version.outputs.VERSION }} .</span>
|
|
<a id="__codelineno-15-21" name="__codelineno-15-21" href="#__codelineno-15-21"></a><span class="w"> </span><span class="no">docker push ghcr.io/fortedigital/hello-world:${{ steps.version.outputs.VERSION }}</span>
|
|
<a id="__codelineno-15-22" name="__codelineno-15-22" href="#__codelineno-15-22"></a>
|
|
<a id="__codelineno-15-23" name="__codelineno-15-23" href="#__codelineno-15-23"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Update helm-values</span>
|
|
<a id="__codelineno-15-24" name="__codelineno-15-24" href="#__codelineno-15-24"></a><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">|</span>
|
|
<a id="__codelineno-15-25" name="__codelineno-15-25" href="#__codelineno-15-25"></a><span class="w"> </span><span class="no">git clone git@github.com:fortedigital/helm-values.git</span>
|
|
<a id="__codelineno-15-26" name="__codelineno-15-26" href="#__codelineno-15-26"></a><span class="w"> </span><span class="no">cd helm-values</span>
|
|
<a id="__codelineno-15-27" name="__codelineno-15-27" href="#__codelineno-15-27"></a><span class="w"> </span><span class="no">mkdir -p hello-world</span>
|
|
<a id="__codelineno-15-28" name="__codelineno-15-28" href="#__codelineno-15-28"></a><span class="w"> </span><span class="no">cat > hello-world/values.yaml <<EOF</span>
|
|
<a id="__codelineno-15-29" name="__codelineno-15-29" href="#__codelineno-15-29"></a><span class="w"> </span><span class="no">app:</span>
|
|
<a id="__codelineno-15-30" name="__codelineno-15-30" href="#__codelineno-15-30"></a><span class="w"> </span><span class="no">image:</span>
|
|
<a id="__codelineno-15-31" name="__codelineno-15-31" href="#__codelineno-15-31"></a><span class="w"> </span><span class="no">repository: ghcr.io/fortedigital/hello-world</span>
|
|
<a id="__codelineno-15-32" name="__codelineno-15-32" href="#__codelineno-15-32"></a><span class="w"> </span><span class="no">tag: ${{ steps.version.outputs.VERSION }}</span>
|
|
<a id="__codelineno-15-33" name="__codelineno-15-33" href="#__codelineno-15-33"></a><span class="w"> </span><span class="no">EOF</span>
|
|
<a id="__codelineno-15-34" name="__codelineno-15-34" href="#__codelineno-15-34"></a><span class="w"> </span><span class="no">git add hello-world/values.yaml</span>
|
|
<a id="__codelineno-15-35" name="__codelineno-15-35" href="#__codelineno-15-35"></a><span class="w"> </span><span class="no">git commit -m "Update hello-world to ${{ steps.version.outputs.VERSION }}"</span>
|
|
<a id="__codelineno-15-36" name="__codelineno-15-36" href="#__codelineno-15-36"></a><span class="w"> </span><span class="no">git push</span>
|
|
</code></pre></div></p>
|
|
</li>
|
|
</ol>
|
|
<h3 id="step-2-create-helm-values">Step 2: Create Helm Values<a class="headerlink" href="#step-2-create-helm-values" title="Permanent link">¶</a></h3>
|
|
<p>Create a folder in <code>helm-values</code> repository:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/helm-prod-values
|
|
<a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a>mkdir<span class="w"> </span>-p<span class="w"> </span>hello-world
|
|
</code></pre></div>
|
|
<p>Create <code>hello-world/values.yaml</code>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="nt">app</span><span class="p">:</span>
|
|
<a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="w"> </span><span class="nt">image</span><span class="p">:</span>
|
|
<a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a><span class="w"> </span><span class="nt">repository</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">ghcr.io/fortedigital/hello-world</span>
|
|
<a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a><span class="w"> </span><span class="nt">tag</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1.0.0</span><span class="w"> </span><span class="c1"># Will be updated by CI/CD</span>
|
|
<a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a><span class="w"> </span><span class="nt">containerPort</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3000</span>
|
|
<a id="__codelineno-17-6" name="__codelineno-17-6" href="#__codelineno-17-6"></a>
|
|
<a id="__codelineno-17-7" name="__codelineno-17-7" href="#__codelineno-17-7"></a><span class="w"> </span><span class="nt">replicaCount</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">1</span>
|
|
<a id="__codelineno-17-8" name="__codelineno-17-8" href="#__codelineno-17-8"></a>
|
|
<a id="__codelineno-17-9" name="__codelineno-17-9" href="#__codelineno-17-9"></a><span class="w"> </span><span class="nt">resources</span><span class="p">:</span>
|
|
<a id="__codelineno-17-10" name="__codelineno-17-10" href="#__codelineno-17-10"></a><span class="w"> </span><span class="nt">requests</span><span class="p">:</span>
|
|
<a id="__codelineno-17-11" name="__codelineno-17-11" href="#__codelineno-17-11"></a><span class="w"> </span><span class="nt">cpu</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">100m</span>
|
|
<a id="__codelineno-17-12" name="__codelineno-17-12" href="#__codelineno-17-12"></a><span class="w"> </span><span class="nt">memory</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">128Mi</span>
|
|
<a id="__codelineno-17-13" name="__codelineno-17-13" href="#__codelineno-17-13"></a><span class="w"> </span><span class="nt">limits</span><span class="p">:</span>
|
|
<a id="__codelineno-17-14" name="__codelineno-17-14" href="#__codelineno-17-14"></a><span class="w"> </span><span class="nt">cpu</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">500m</span>
|
|
<a id="__codelineno-17-15" name="__codelineno-17-15" href="#__codelineno-17-15"></a><span class="w"> </span><span class="nt">memory</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">512Mi</span>
|
|
<a id="__codelineno-17-16" name="__codelineno-17-16" href="#__codelineno-17-16"></a>
|
|
<a id="__codelineno-17-17" name="__codelineno-17-17" href="#__codelineno-17-17"></a><span class="w"> </span><span class="nt">extraEnv</span><span class="p">:</span>
|
|
<a id="__codelineno-17-18" name="__codelineno-17-18" href="#__codelineno-17-18"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">PORT</span>
|
|
<a id="__codelineno-17-19" name="__codelineno-17-19" href="#__codelineno-17-19"></a><span class="w"> </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="s">"3000"</span>
|
|
<a id="__codelineno-17-20" name="__codelineno-17-20" href="#__codelineno-17-20"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">NODE_ENV</span>
|
|
<a id="__codelineno-17-21" name="__codelineno-17-21" href="#__codelineno-17-21"></a><span class="w"> </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="s">"production"</span>
|
|
<a id="__codelineno-17-22" name="__codelineno-17-22" href="#__codelineno-17-22"></a>
|
|
<a id="__codelineno-17-23" name="__codelineno-17-23" href="#__codelineno-17-23"></a><span class="w"> </span><span class="nt">envSecretName</span><span class="p">:</span><span class="w"> </span><span class="s">""</span><span class="w"> </span><span class="c1"># Optional: reference to secrets</span>
|
|
<a id="__codelineno-17-24" name="__codelineno-17-24" href="#__codelineno-17-24"></a>
|
|
<a id="__codelineno-17-25" name="__codelineno-17-25" href="#__codelineno-17-25"></a><span class="nt">service</span><span class="p">:</span>
|
|
<a id="__codelineno-17-26" name="__codelineno-17-26" href="#__codelineno-17-26"></a><span class="w"> </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3000</span>
|
|
<a id="__codelineno-17-27" name="__codelineno-17-27" href="#__codelineno-17-27"></a>
|
|
<a id="__codelineno-17-28" name="__codelineno-17-28" href="#__codelineno-17-28"></a><span class="nt">ingress</span><span class="p">:</span>
|
|
<a id="__codelineno-17-29" name="__codelineno-17-29" href="#__codelineno-17-29"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-17-30" name="__codelineno-17-30" href="#__codelineno-17-30"></a><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">hello-world.forteapps.net</span><span class="w"> </span><span class="c1"># Your subdomain</span>
|
|
<a id="__codelineno-17-31" name="__codelineno-17-31" href="#__codelineno-17-31"></a>
|
|
<a id="__codelineno-17-32" name="__codelineno-17-32" href="#__codelineno-17-32"></a><span class="nt">db</span><span class="p">:</span>
|
|
<a id="__codelineno-17-33" name="__codelineno-17-33" href="#__codelineno-17-33"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">false</span><span class="w"> </span><span class="c1"># Set to true if you need PostgreSQL</span>
|
|
</code></pre></div></p>
|
|
<p>Commit and push:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a>git<span class="w"> </span>add<span class="w"> </span>hello-world/values.yaml
|
|
<a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Add hello-world application values"</span>
|
|
<a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a>git<span class="w"> </span>push
|
|
</code></pre></div></p>
|
|
<h3 id="step-3-create-argocd-application-manifest">Step 3: Create ArgoCD Application Manifest<a class="headerlink" href="#step-3-create-argocd-application-manifest" title="Permanent link">¶</a></h3>
|
|
<p>In the <code>launchpad</code> repository, create <code>apps/hello-world.yaml</code>:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">argoproj.io/v1alpha1</span>
|
|
<a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Application</span>
|
|
<a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a><span class="nt">metadata</span><span class="p">:</span>
|
|
<a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">hello-world</span>
|
|
<a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a><span class="w"> </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">argocd</span>
|
|
<a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span>
|
|
<a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a><span class="w"> </span><span class="nt">argocd.argoproj.io/sync-wave</span><span class="p">:</span><span class="w"> </span><span class="s">"1"</span>
|
|
<a id="__codelineno-19-8" name="__codelineno-19-8" href="#__codelineno-19-8"></a><span class="w"> </span><span class="nt">notifications.argoproj.io/subscribe.on-sync-succeeded.slack</span><span class="p">:</span><span class="w"> </span><span class="s">""</span>
|
|
<a id="__codelineno-19-9" name="__codelineno-19-9" href="#__codelineno-19-9"></a><span class="w"> </span><span class="nt">notifications.argoproj.io/subscribe.on-sync-failed.slack</span><span class="p">:</span><span class="w"> </span><span class="s">""</span>
|
|
<a id="__codelineno-19-10" name="__codelineno-19-10" href="#__codelineno-19-10"></a><span class="w"> </span><span class="nt">notifications.argoproj.io/subscribe.on-degraded.slack</span><span class="p">:</span><span class="w"> </span><span class="s">""</span>
|
|
<a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a><span class="w"> </span><span class="nt">labels</span><span class="p">:</span>
|
|
<a id="__codelineno-19-12" name="__codelineno-19-12" href="#__codelineno-19-12"></a><span class="w"> </span><span class="nt">app.kubernetes.io/name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">hello-world</span>
|
|
<a id="__codelineno-19-13" name="__codelineno-19-13" href="#__codelineno-19-13"></a><span class="w"> </span><span class="nt">app.kubernetes.io/part-of</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">apps</span>
|
|
<a id="__codelineno-19-14" name="__codelineno-19-14" href="#__codelineno-19-14"></a><span class="w"> </span><span class="nt">app.kubernetes.io/managed-by</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">argocd</span>
|
|
<a id="__codelineno-19-15" name="__codelineno-19-15" href="#__codelineno-19-15"></a><span class="w"> </span><span class="nt">finalizers</span><span class="p">:</span>
|
|
<a id="__codelineno-19-16" name="__codelineno-19-16" href="#__codelineno-19-16"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">resources-finalizer.argocd.argoproj.io</span>
|
|
<a id="__codelineno-19-17" name="__codelineno-19-17" href="#__codelineno-19-17"></a>
|
|
<a id="__codelineno-19-18" name="__codelineno-19-18" href="#__codelineno-19-18"></a><span class="nt">spec</span><span class="p">:</span>
|
|
<a id="__codelineno-19-19" name="__codelineno-19-19" href="#__codelineno-19-19"></a><span class="w"> </span><span class="nt">project</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">default</span>
|
|
<a id="__codelineno-19-20" name="__codelineno-19-20" href="#__codelineno-19-20"></a>
|
|
<a id="__codelineno-19-21" name="__codelineno-19-21" href="#__codelineno-19-21"></a><span class="w"> </span><span class="nt">sources</span><span class="p">:</span>
|
|
<a id="__codelineno-19-22" name="__codelineno-19-22" href="#__codelineno-19-22"></a><span class="w"> </span><span class="c1"># Source 1: Helm chart templates</span>
|
|
<a id="__codelineno-19-23" name="__codelineno-19-23" href="#__codelineno-19-23"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">repoURL</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/fortedigital/forte-helm</span>
|
|
<a id="__codelineno-19-24" name="__codelineno-19-24" href="#__codelineno-19-24"></a><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">forteapp</span>
|
|
<a id="__codelineno-19-25" name="__codelineno-19-25" href="#__codelineno-19-25"></a><span class="w"> </span><span class="nt">targetRevision</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">HEAD</span>
|
|
<a id="__codelineno-19-26" name="__codelineno-19-26" href="#__codelineno-19-26"></a><span class="w"> </span><span class="nt">helm</span><span class="p">:</span>
|
|
<a id="__codelineno-19-27" name="__codelineno-19-27" href="#__codelineno-19-27"></a><span class="w"> </span><span class="nt">valueFiles</span><span class="p">:</span>
|
|
<a id="__codelineno-19-28" name="__codelineno-19-28" href="#__codelineno-19-28"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">$values/hello-world/values.yaml</span>
|
|
<a id="__codelineno-19-29" name="__codelineno-19-29" href="#__codelineno-19-29"></a>
|
|
<a id="__codelineno-19-30" name="__codelineno-19-30" href="#__codelineno-19-30"></a><span class="w"> </span><span class="c1"># Source 2: Helm values</span>
|
|
<a id="__codelineno-19-31" name="__codelineno-19-31" href="#__codelineno-19-31"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">repoURL</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">git@github.com:fortedigital/helm-values.git</span>
|
|
<a id="__codelineno-19-32" name="__codelineno-19-32" href="#__codelineno-19-32"></a><span class="w"> </span><span class="nt">targetRevision</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">HEAD</span>
|
|
<a id="__codelineno-19-33" name="__codelineno-19-33" href="#__codelineno-19-33"></a><span class="w"> </span><span class="nt">ref</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">values</span>
|
|
<a id="__codelineno-19-34" name="__codelineno-19-34" href="#__codelineno-19-34"></a>
|
|
<a id="__codelineno-19-35" name="__codelineno-19-35" href="#__codelineno-19-35"></a><span class="w"> </span><span class="nt">destination</span><span class="p">:</span>
|
|
<a id="__codelineno-19-36" name="__codelineno-19-36" href="#__codelineno-19-36"></a><span class="w"> </span><span class="nt">server</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://kubernetes.default.svc</span>
|
|
<a id="__codelineno-19-37" name="__codelineno-19-37" href="#__codelineno-19-37"></a><span class="w"> </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">hello-world</span>
|
|
<a id="__codelineno-19-38" name="__codelineno-19-38" href="#__codelineno-19-38"></a>
|
|
<a id="__codelineno-19-39" name="__codelineno-19-39" href="#__codelineno-19-39"></a><span class="w"> </span><span class="nt">syncPolicy</span><span class="p">:</span>
|
|
<a id="__codelineno-19-40" name="__codelineno-19-40" href="#__codelineno-19-40"></a><span class="w"> </span><span class="nt">automated</span><span class="p">:</span>
|
|
<a id="__codelineno-19-41" name="__codelineno-19-41" href="#__codelineno-19-41"></a><span class="w"> </span><span class="nt">prune</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-19-42" name="__codelineno-19-42" href="#__codelineno-19-42"></a><span class="w"> </span><span class="nt">selfHeal</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-19-43" name="__codelineno-19-43" href="#__codelineno-19-43"></a><span class="w"> </span><span class="nt">allowEmpty</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">false</span>
|
|
<a id="__codelineno-19-44" name="__codelineno-19-44" href="#__codelineno-19-44"></a>
|
|
<a id="__codelineno-19-45" name="__codelineno-19-45" href="#__codelineno-19-45"></a><span class="w"> </span><span class="nt">syncOptions</span><span class="p">:</span>
|
|
<a id="__codelineno-19-46" name="__codelineno-19-46" href="#__codelineno-19-46"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">CreateNamespace=true</span>
|
|
<a id="__codelineno-19-47" name="__codelineno-19-47" href="#__codelineno-19-47"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Validate=true</span>
|
|
<a id="__codelineno-19-48" name="__codelineno-19-48" href="#__codelineno-19-48"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">ServerSideApply=true</span>
|
|
<a id="__codelineno-19-49" name="__codelineno-19-49" href="#__codelineno-19-49"></a>
|
|
<a id="__codelineno-19-50" name="__codelineno-19-50" href="#__codelineno-19-50"></a><span class="w"> </span><span class="nt">retry</span><span class="p">:</span>
|
|
<a id="__codelineno-19-51" name="__codelineno-19-51" href="#__codelineno-19-51"></a><span class="w"> </span><span class="nt">limit</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">5</span>
|
|
<a id="__codelineno-19-52" name="__codelineno-19-52" href="#__codelineno-19-52"></a><span class="w"> </span><span class="nt">backoff</span><span class="p">:</span>
|
|
<a id="__codelineno-19-53" name="__codelineno-19-53" href="#__codelineno-19-53"></a><span class="w"> </span><span class="nt">duration</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">5s</span>
|
|
<a id="__codelineno-19-54" name="__codelineno-19-54" href="#__codelineno-19-54"></a><span class="w"> </span><span class="nt">factor</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">2</span>
|
|
<a id="__codelineno-19-55" name="__codelineno-19-55" href="#__codelineno-19-55"></a><span class="w"> </span><span class="nt">maxDuration</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3m</span>
|
|
<a id="__codelineno-19-56" name="__codelineno-19-56" href="#__codelineno-19-56"></a>
|
|
<a id="__codelineno-19-57" name="__codelineno-19-57" href="#__codelineno-19-57"></a><span class="w"> </span><span class="nt">ignoreDifferences</span><span class="p">:</span>
|
|
<a id="__codelineno-19-58" name="__codelineno-19-58" href="#__codelineno-19-58"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">group</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">apps</span>
|
|
<a id="__codelineno-19-59" name="__codelineno-19-59" href="#__codelineno-19-59"></a><span class="w"> </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Deployment</span>
|
|
<a id="__codelineno-19-60" name="__codelineno-19-60" href="#__codelineno-19-60"></a><span class="w"> </span><span class="nt">jsonPointers</span><span class="p">:</span>
|
|
<a id="__codelineno-19-61" name="__codelineno-19-61" href="#__codelineno-19-61"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/spec/replicas</span>
|
|
</code></pre></div>
|
|
<p>Commit and push:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/launchpad
|
|
<a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a>git<span class="w"> </span>add<span class="w"> </span>apps/hello-world.yaml
|
|
<a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Add hello-world application"</span>
|
|
<a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a>git<span class="w"> </span>push
|
|
</code></pre></div></p>
|
|
<h3 id="step-4-verify-deployment">Step 4: Verify Deployment<a class="headerlink" href="#step-4-verify-deployment" title="Permanent link">¶</a></h3>
|
|
<p>ArgoCD will automatically detect the new application within 60 seconds.</p>
|
|
<p><strong>Option 1: Check Slack</strong>
|
|
- Watch for sync notifications in your Slack channel
|
|
- ✅ "Application hello-world sync succeeded"</p>
|
|
<p><strong>Option 2: Check ArgoCD UI</strong> (if you have access)
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="c1"># Port forward to ArgoCD UI</span>
|
|
<a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a>kubectl<span class="w"> </span>port-forward<span class="w"> </span>svc/argocd-server<span class="w"> </span>-n<span class="w"> </span>argocd<span class="w"> </span><span class="m">8080</span>:443
|
|
<a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a>
|
|
<a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="c1"># Open browser: https://localhost:8080</span>
|
|
<a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a><span class="c1"># Look for "hello-world" application</span>
|
|
</code></pre></div></p>
|
|
<p><strong>Option 3: Check with kubectl</strong> (if you have access)
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="c1"># List ArgoCD applications</span>
|
|
<a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>applications<span class="w"> </span>-n<span class="w"> </span>argocd
|
|
<a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a>
|
|
<a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a><span class="c1"># Check application status</span>
|
|
<a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a>kubectl<span class="w"> </span>get<span class="w"> </span>application<span class="w"> </span>hello-world<span class="w"> </span>-n<span class="w"> </span>argocd
|
|
<a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a>
|
|
<a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-7"></a><span class="c1"># Verify pods are running</span>
|
|
<a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-8"></a>kubectl<span class="w"> </span>get<span class="w"> </span>pods<span class="w"> </span>-n<span class="w"> </span>hello-world
|
|
</code></pre></div></p>
|
|
<h3 id="step-5-access-your-application">Step 5: Access Your Application<a class="headerlink" href="#step-5-access-your-application" title="Permanent link">¶</a></h3>
|
|
<p>Once deployed, access via the configured domain:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="c1"># Check if ingress is created</span>
|
|
<a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>ingressroute<span class="w"> </span>-n<span class="w"> </span>hello-world
|
|
<a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a>
|
|
<a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a><span class="c1"># Access application</span>
|
|
<a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a>curl<span class="w"> </span>https://hello-world.forteapps.net
|
|
</code></pre></div>
|
|
<p><strong>⚠️ Note</strong>: DNS must be manually configured for new subdomains. Contact the platform team to add DNS records.</p>
|
|
<hr />
|
|
<h2 id="updating-an-existing-application">Updating an Existing Application<a class="headerlink" href="#updating-an-existing-application" title="Permanent link">¶</a></h2>
|
|
<h3 id="scenario-deploying-a-code-change">Scenario: Deploying a Code Change<a class="headerlink" href="#scenario-deploying-a-code-change" title="Permanent link">¶</a></h3>
|
|
<p>You've made changes to your application code and want to deploy them.</p>
|
|
<h3 id="method-1-automatic-recommended">Method 1: Automatic (Recommended)<a class="headerlink" href="#method-1-automatic-recommended" title="Permanent link">¶</a></h3>
|
|
<p><strong>Just push to <code>main</code> branch</strong> - CI/CD handles everything:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="c1"># In your application repository</span>
|
|
<a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a>git<span class="w"> </span>add<span class="w"> </span>.
|
|
<a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Fix bug in user login"</span>
|
|
<a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a>git<span class="w"> </span>push<span class="w"> </span>origin<span class="w"> </span>main
|
|
</code></pre></div>
|
|
<p><strong>What Happens Next:</strong>
|
|
1. ✅ GitHub Actions triggers
|
|
2. ✅ Builds new Docker image
|
|
3. ✅ Tags with new version (e.g., <code>v20260316-143022</code>)
|
|
4. ✅ Pushes to container registry
|
|
5. ✅ Updates <code>helm-values/myapp/values.yaml</code> with new tag
|
|
6. ✅ ArgoCD detects change
|
|
7. ✅ Syncs new version to cluster
|
|
8. ✅ Sends Slack notification</p>
|
|
<p><strong>Timeline</strong>: ~5-10 minutes from push to deployment</p>
|
|
<h3 id="method-2-manual-image-tag-update">Method 2: Manual Image Tag Update<a class="headerlink" href="#method-2-manual-image-tag-update" title="Permanent link">¶</a></h3>
|
|
<p>If CI/CD is not set up, manually update the image tag:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/helm-prod-values
|
|
<a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a>
|
|
<a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="c1"># Edit your app's values.yaml</span>
|
|
<a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a>vim<span class="w"> </span>myapp/values.yaml
|
|
<a id="__codelineno-25-5" name="__codelineno-25-5" href="#__codelineno-25-5"></a>
|
|
<a id="__codelineno-25-6" name="__codelineno-25-6" href="#__codelineno-25-6"></a><span class="c1"># Change:</span>
|
|
<a id="__codelineno-25-7" name="__codelineno-25-7" href="#__codelineno-25-7"></a>app:
|
|
<a id="__codelineno-25-8" name="__codelineno-25-8" href="#__codelineno-25-8"></a><span class="w"> </span>image:
|
|
<a id="__codelineno-25-9" name="__codelineno-25-9" href="#__codelineno-25-9"></a><span class="w"> </span>tag:<span class="w"> </span>v1.0.0<span class="w"> </span><span class="c1"># Old version</span>
|
|
<a id="__codelineno-25-10" name="__codelineno-25-10" href="#__codelineno-25-10"></a><span class="c1"># To:</span>
|
|
<a id="__codelineno-25-11" name="__codelineno-25-11" href="#__codelineno-25-11"></a>app:
|
|
<a id="__codelineno-25-12" name="__codelineno-25-12" href="#__codelineno-25-12"></a><span class="w"> </span>image:
|
|
<a id="__codelineno-25-13" name="__codelineno-25-13" href="#__codelineno-25-13"></a><span class="w"> </span>tag:<span class="w"> </span>v1.0.1<span class="w"> </span><span class="c1"># New version</span>
|
|
<a id="__codelineno-25-14" name="__codelineno-25-14" href="#__codelineno-25-14"></a>
|
|
<a id="__codelineno-25-15" name="__codelineno-25-15" href="#__codelineno-25-15"></a><span class="c1"># Commit and push</span>
|
|
<a id="__codelineno-25-16" name="__codelineno-25-16" href="#__codelineno-25-16"></a>git<span class="w"> </span>add<span class="w"> </span>myapp/values.yaml
|
|
<a id="__codelineno-25-17" name="__codelineno-25-17" href="#__codelineno-25-17"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Update myapp to v1.0.1"</span>
|
|
<a id="__codelineno-25-18" name="__codelineno-25-18" href="#__codelineno-25-18"></a>git<span class="w"> </span>push
|
|
</code></pre></div>
|
|
<p>ArgoCD will sync within 60 seconds.</p>
|
|
<h3 id="method-3-configuration-changes">Method 3: Configuration Changes<a class="headerlink" href="#method-3-configuration-changes" title="Permanent link">¶</a></h3>
|
|
<p>To update environment variables, resources, or other config:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/helm-prod-values
|
|
<a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>vim<span class="w"> </span>myapp/values.yaml
|
|
</code></pre></div>
|
|
<p>Example changes:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="nt">app</span><span class="p">:</span>
|
|
<a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a><span class="w"> </span><span class="c1"># Increase resources</span>
|
|
<a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a><span class="w"> </span><span class="nt">resources</span><span class="p">:</span>
|
|
<a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a><span class="w"> </span><span class="nt">requests</span><span class="p">:</span>
|
|
<a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a><span class="w"> </span><span class="nt">cpu</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">200m</span><span class="w"> </span><span class="c1"># Was 100m</span>
|
|
<a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a><span class="w"> </span><span class="nt">memory</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">256Mi</span><span class="w"> </span><span class="c1"># Was 128Mi</span>
|
|
<a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a>
|
|
<a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a><span class="w"> </span><span class="c1"># Add new environment variable</span>
|
|
<a id="__codelineno-27-9" name="__codelineno-27-9" href="#__codelineno-27-9"></a><span class="w"> </span><span class="nt">extraEnv</span><span class="p">:</span>
|
|
<a id="__codelineno-27-10" name="__codelineno-27-10" href="#__codelineno-27-10"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">API_URL</span>
|
|
<a id="__codelineno-27-11" name="__codelineno-27-11" href="#__codelineno-27-11"></a><span class="w"> </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://api.example.com</span>
|
|
<a id="__codelineno-27-12" name="__codelineno-27-12" href="#__codelineno-27-12"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">DEBUG</span><span class="w"> </span><span class="c1"># NEW</span>
|
|
<a id="__codelineno-27-13" name="__codelineno-27-13" href="#__codelineno-27-13"></a><span class="w"> </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="s">"true"</span><span class="w"> </span><span class="c1"># NEW</span>
|
|
<a id="__codelineno-27-14" name="__codelineno-27-14" href="#__codelineno-27-14"></a>
|
|
<a id="__codelineno-27-15" name="__codelineno-27-15" href="#__codelineno-27-15"></a><span class="w"> </span><span class="c1"># Enable HPA</span>
|
|
<a id="__codelineno-27-16" name="__codelineno-27-16" href="#__codelineno-27-16"></a><span class="w"> </span><span class="nt">hpa</span><span class="p">:</span>
|
|
<a id="__codelineno-27-17" name="__codelineno-27-17" href="#__codelineno-27-17"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span><span class="w"> </span><span class="c1"># Was false</span>
|
|
<a id="__codelineno-27-18" name="__codelineno-27-18" href="#__codelineno-27-18"></a><span class="w"> </span><span class="nt">minReplicas</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">2</span>
|
|
<a id="__codelineno-27-19" name="__codelineno-27-19" href="#__codelineno-27-19"></a><span class="w"> </span><span class="nt">maxReplicas</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">10</span>
|
|
</code></pre></div>
|
|
<p>Commit and push:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a>git<span class="w"> </span>add<span class="w"> </span>myapp/values.yaml
|
|
<a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Increase myapp resources and enable HPA"</span>
|
|
<a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a>git<span class="w"> </span>push
|
|
</code></pre></div></p>
|
|
<h3 id="method-4-application-manifest-changes">Method 4: Application Manifest Changes<a class="headerlink" href="#method-4-application-manifest-changes" title="Permanent link">¶</a></h3>
|
|
<p>To change ArgoCD sync behavior, namespace, or other meta-config:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/launchpad
|
|
<a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a>vim<span class="w"> </span>apps/myapp.yaml
|
|
</code></pre></div>
|
|
<p>Example changes:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="nt">spec</span><span class="p">:</span>
|
|
<a id="__codelineno-30-2" name="__codelineno-30-2" href="#__codelineno-30-2"></a><span class="w"> </span><span class="nt">syncPolicy</span><span class="p">:</span>
|
|
<a id="__codelineno-30-3" name="__codelineno-30-3" href="#__codelineno-30-3"></a><span class="w"> </span><span class="nt">automated</span><span class="p">:</span>
|
|
<a id="__codelineno-30-4" name="__codelineno-30-4" href="#__codelineno-30-4"></a><span class="w"> </span><span class="nt">prune</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-30-5" name="__codelineno-30-5" href="#__codelineno-30-5"></a><span class="w"> </span><span class="nt">selfHeal</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">false</span><span class="w"> </span><span class="c1"># Disable self-healing temporarily</span>
|
|
</code></pre></div>
|
|
<p>Commit and push:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a>git<span class="w"> </span>add<span class="w"> </span>apps/myapp.yaml
|
|
<a id="__codelineno-31-2" name="__codelineno-31-2" href="#__codelineno-31-2"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Disable self-healing for myapp"</span>
|
|
<a id="__codelineno-31-3" name="__codelineno-31-3" href="#__codelineno-31-3"></a>git<span class="w"> </span>push
|
|
</code></pre></div></p>
|
|
<hr />
|
|
<h2 id="working-with-secrets">Working with Secrets<a class="headerlink" href="#working-with-secrets" title="Permanent link">¶</a></h2>
|
|
<h3 id="understanding-secret-management">Understanding Secret Management<a class="headerlink" href="#understanding-secret-management" title="Permanent link">¶</a></h3>
|
|
<p><strong>NEVER commit plain secrets to Git.</strong> We use <strong>Sealed Secrets</strong> to encrypt secrets before committing.</p>
|
|
<h3 id="creating-a-new-secret">Creating a New Secret<a class="headerlink" href="#creating-a-new-secret" title="Permanent link">¶</a></h3>
|
|
<h4 id="step-1-create-plain-secret-locally">Step 1: Create Plain Secret Locally<a class="headerlink" href="#step-1-create-plain-secret-locally" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/launchpad
|
|
<a id="__codelineno-32-2" name="__codelineno-32-2" href="#__codelineno-32-2"></a>
|
|
<a id="__codelineno-32-3" name="__codelineno-32-3" href="#__codelineno-32-3"></a><span class="c1"># Create secret in private/ folder (Git-ignored)</span>
|
|
<a id="__codelineno-32-4" name="__codelineno-32-4" href="#__codelineno-32-4"></a>kubectl<span class="w"> </span>create<span class="w"> </span>secret<span class="w"> </span>generic<span class="w"> </span>myapp-credentials<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-32-5" name="__codelineno-32-5" href="#__codelineno-32-5"></a><span class="w"> </span>--from-literal<span class="o">=</span><span class="nv">API_KEY</span><span class="o">=</span>your-secret-key-here<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-32-6" name="__codelineno-32-6" href="#__codelineno-32-6"></a><span class="w"> </span>--from-literal<span class="o">=</span><span class="nv">DB_PASSWORD</span><span class="o">=</span>super-secret-password<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-32-7" name="__codelineno-32-7" href="#__codelineno-32-7"></a><span class="w"> </span>--dry-run<span class="o">=</span>client<span class="w"> </span>-o<span class="w"> </span>yaml<span class="w"> </span>><span class="w"> </span>private/myapp-credentials.yaml
|
|
</code></pre></div>
|
|
<p><strong>DO NOT commit this file!</strong> It's in <code>private/</code> which is Git-ignored.</p>
|
|
<h4 id="step-2-seal-the-secret">Step 2: Seal the Secret<a class="headerlink" href="#step-2-seal-the-secret" title="Permanent link">¶</a></h4>
|
|
<p>Get the public certificate (one-time setup):</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="c1"># Fetch public cert from cluster</span>
|
|
<a id="__codelineno-33-2" name="__codelineno-33-2" href="#__codelineno-33-2"></a>kubeseal<span class="w"> </span>--fetch-cert<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-33-3" name="__codelineno-33-3" href="#__codelineno-33-3"></a><span class="w"> </span>--controller-name<span class="o">=</span>sealed-secrets-controller<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-33-4" name="__codelineno-33-4" href="#__codelineno-33-4"></a><span class="w"> </span>--controller-namespace<span class="o">=</span>kube-system<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-33-5" name="__codelineno-33-5" href="#__codelineno-33-5"></a><span class="w"> </span>><span class="w"> </span>pub-cert.pem
|
|
</code></pre></div>
|
|
<p>Seal your secret:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a>kubeseal<span class="w"> </span>--format<span class="o">=</span>yaml<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a><span class="w"> </span>--cert<span class="o">=</span>pub-cert.pem<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-34-3" name="__codelineno-34-3" href="#__codelineno-34-3"></a><span class="w"> </span><<span class="w"> </span>private/myapp-credentials.yaml<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-34-4" name="__codelineno-34-4" href="#__codelineno-34-4"></a><span class="w"> </span>><span class="w"> </span>secrets/myapp-credentials-sealed.yaml
|
|
</code></pre></div>
|
|
<h4 id="step-3-commit-sealed-secret">Step 3: Commit Sealed Secret<a class="headerlink" href="#step-3-commit-sealed-secret" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a>git<span class="w"> </span>add<span class="w"> </span>secrets/myapp-credentials-sealed.yaml
|
|
<a id="__codelineno-35-2" name="__codelineno-35-2" href="#__codelineno-35-2"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Add myapp credentials (sealed)"</span>
|
|
<a id="__codelineno-35-3" name="__codelineno-35-3" href="#__codelineno-35-3"></a>git<span class="w"> </span>push
|
|
</code></pre></div>
|
|
<h4 id="step-4-reference-secret-in-application">Step 4: Reference Secret in Application<a class="headerlink" href="#step-4-reference-secret-in-application" title="Permanent link">¶</a></h4>
|
|
<p>Update your <code>helm-values/myapp/values.yaml</code>:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a><span class="nt">app</span><span class="p">:</span>
|
|
<a id="__codelineno-36-2" name="__codelineno-36-2" href="#__codelineno-36-2"></a><span class="w"> </span><span class="nt">envSecretName</span><span class="p">:</span><span class="w"> </span><span class="s">"myapp-credentials"</span><span class="w"> </span><span class="c1"># References the SealedSecret</span>
|
|
</code></pre></div>
|
|
<p>Commit and push:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/helm-prod-values
|
|
<a id="__codelineno-37-2" name="__codelineno-37-2" href="#__codelineno-37-2"></a>git<span class="w"> </span>add<span class="w"> </span>myapp/values.yaml
|
|
<a id="__codelineno-37-3" name="__codelineno-37-3" href="#__codelineno-37-3"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Reference myapp credentials"</span>
|
|
<a id="__codelineno-37-4" name="__codelineno-37-4" href="#__codelineno-37-4"></a>git<span class="w"> </span>push
|
|
</code></pre></div></p>
|
|
<h3 id="updating-a-secret">Updating a Secret<a class="headerlink" href="#updating-a-secret" title="Permanent link">¶</a></h3>
|
|
<p>To update an existing secret:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a><span class="c1"># 1. Create new version of secret</span>
|
|
<a id="__codelineno-38-2" name="__codelineno-38-2" href="#__codelineno-38-2"></a>kubectl<span class="w"> </span>create<span class="w"> </span>secret<span class="w"> </span>generic<span class="w"> </span>myapp-credentials<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-38-3" name="__codelineno-38-3" href="#__codelineno-38-3"></a><span class="w"> </span>--from-literal<span class="o">=</span><span class="nv">API_KEY</span><span class="o">=</span>new-key-here<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-38-4" name="__codelineno-38-4" href="#__codelineno-38-4"></a><span class="w"> </span>--from-literal<span class="o">=</span><span class="nv">DB_PASSWORD</span><span class="o">=</span>new-password<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-38-5" name="__codelineno-38-5" href="#__codelineno-38-5"></a><span class="w"> </span>--dry-run<span class="o">=</span>client<span class="w"> </span>-o<span class="w"> </span>yaml<span class="w"> </span>><span class="w"> </span>private/myapp-credentials.yaml
|
|
<a id="__codelineno-38-6" name="__codelineno-38-6" href="#__codelineno-38-6"></a>
|
|
<a id="__codelineno-38-7" name="__codelineno-38-7" href="#__codelineno-38-7"></a><span class="c1"># 2. Seal it</span>
|
|
<a id="__codelineno-38-8" name="__codelineno-38-8" href="#__codelineno-38-8"></a>kubeseal<span class="w"> </span>--format<span class="o">=</span>yaml<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-38-9" name="__codelineno-38-9" href="#__codelineno-38-9"></a><span class="w"> </span>--cert<span class="o">=</span>pub-cert.pem<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-38-10" name="__codelineno-38-10" href="#__codelineno-38-10"></a><span class="w"> </span><<span class="w"> </span>private/myapp-credentials.yaml<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-38-11" name="__codelineno-38-11" href="#__codelineno-38-11"></a><span class="w"> </span>><span class="w"> </span>secrets/myapp-credentials-sealed.yaml
|
|
<a id="__codelineno-38-12" name="__codelineno-38-12" href="#__codelineno-38-12"></a>
|
|
<a id="__codelineno-38-13" name="__codelineno-38-13" href="#__codelineno-38-13"></a><span class="c1"># 3. Commit sealed version</span>
|
|
<a id="__codelineno-38-14" name="__codelineno-38-14" href="#__codelineno-38-14"></a>git<span class="w"> </span>add<span class="w"> </span>secrets/myapp-credentials-sealed.yaml
|
|
<a id="__codelineno-38-15" name="__codelineno-38-15" href="#__codelineno-38-15"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Update myapp credentials"</span>
|
|
<a id="__codelineno-38-16" name="__codelineno-38-16" href="#__codelineno-38-16"></a>git<span class="w"> </span>push
|
|
<a id="__codelineno-38-17" name="__codelineno-38-17" href="#__codelineno-38-17"></a>
|
|
<a id="__codelineno-38-18" name="__codelineno-38-18" href="#__codelineno-38-18"></a><span class="c1"># 4. Restart pods to pick up new secret</span>
|
|
<a id="__codelineno-38-19" name="__codelineno-38-19" href="#__codelineno-38-19"></a>kubectl<span class="w"> </span>rollout<span class="w"> </span>restart<span class="w"> </span>deployment<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
</code></pre></div>
|
|
<h3 id="secret-best-practices">Secret Best Practices<a class="headerlink" href="#secret-best-practices" title="Permanent link">¶</a></h3>
|
|
<p>✅ <strong>DO</strong>:
|
|
- Store secrets in <code>private/</code> folder locally
|
|
- Always seal secrets before committing
|
|
- Delete plain secrets after sealing
|
|
- Use meaningful secret names
|
|
- Document what each secret contains</p>
|
|
<p>❌ <strong>DON'T</strong>:
|
|
- Commit plain secrets to Git
|
|
- Share secrets via Slack/email
|
|
- Hard-code secrets in code
|
|
- Use the same secret across multiple environments
|
|
- Store secrets in Docker images</p>
|
|
<h3 id="where-secrets-are-stored">Where Secrets Are Stored<a class="headerlink" href="#where-secrets-are-stored" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a>┌─────────────────────────────────────────────────────────────┐
|
|
<a id="__codelineno-39-2" name="__codelineno-39-2" href="#__codelineno-39-2"></a>│ Location │ Content │ Committed?│
|
|
<a id="__codelineno-39-3" name="__codelineno-39-3" href="#__codelineno-39-3"></a>├──────────────────────────┼────────────────────┼────────────┤
|
|
<a id="__codelineno-39-4" name="__codelineno-39-4" href="#__codelineno-39-4"></a>│ private/ │ Plain secrets │ ❌ NO │
|
|
<a id="__codelineno-39-5" name="__codelineno-39-5" href="#__codelineno-39-5"></a>│ secrets/ │ Sealed secrets │ ✅ YES │
|
|
<a id="__codelineno-39-6" name="__codelineno-39-6" href="#__codelineno-39-6"></a>│ Kubernetes cluster │ Unsealed secrets │ N/A │
|
|
<a id="__codelineno-39-7" name="__codelineno-39-7" href="#__codelineno-39-7"></a>└─────────────────────────────────────────────────────────────┘
|
|
</code></pre></div>
|
|
<p><strong>Sealed Secrets Controller</strong> in the cluster decrypts sealed secrets automatically.</p>
|
|
<hr />
|
|
<h2 id="enabling-authentication-for-applications">Enabling Authentication for Applications<a class="headerlink" href="#enabling-authentication-for-applications" title="Permanent link">¶</a></h2>
|
|
<p>The cluster supports automatic authentication sidecar injection for applications via Kyverno policies. This allows you to add authentication to your applications without modifying application code.</p>
|
|
<h3 id="how-it-works">How It Works<a class="headerlink" href="#how-it-works" title="Permanent link">¶</a></h3>
|
|
<p>When you enable authentication in your Helm values, the Kyverno policy automatically:
|
|
1. ✅ Injects an authentication sidecar container into your pod
|
|
2. ✅ Routes all incoming traffic through the auth sidecar (port 8080)
|
|
3. ✅ Validates credentials before forwarding requests to your application
|
|
4. ✅ Creates necessary secrets (if they don't exist)
|
|
5. ✅ Adds a NetworkPolicy to restrict ingress</p>
|
|
<p><strong>Architecture</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a>Internet → Traefik → Service:8080 → Auth Sidecar:8080 → localhost → Your App:3000
|
|
<a id="__codelineno-40-2" name="__codelineno-40-2" href="#__codelineno-40-2"></a> │
|
|
<a id="__codelineno-40-3" name="__codelineno-40-3" href="#__codelineno-40-3"></a> ├─ Validates credentials
|
|
<a id="__codelineno-40-4" name="__codelineno-40-4" href="#__codelineno-40-4"></a> └─ Forwards if valid
|
|
</code></pre></div></p>
|
|
<h3 id="authentication-modes">Authentication Modes<a class="headerlink" href="#authentication-modes" title="Permanent link">¶</a></h3>
|
|
<p>Three authentication modes are supported:
|
|
1. <strong>Token-based</strong>: Static tokens (simple, good for service-to-service or internal apps)
|
|
2. <strong>OIDC</strong>: OpenID Connect (full SSO, good for user-facing apps)
|
|
3. <strong>MCP</strong>: OAuth 2.0 for MCP servers via RFC 9728 / RFC 7591 (good for MCP tool servers requiring OAuth-based access control)</p>
|
|
<hr />
|
|
<h3 id="token-based-authentication">Token-Based Authentication<a class="headerlink" href="#token-based-authentication" title="Permanent link">¶</a></h3>
|
|
<h4 id="step-1-configure-helm-values">Step 1: Configure Helm Values<a class="headerlink" href="#step-1-configure-helm-values" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a><span class="c1"># In helm-values/myapp/values.yaml</span>
|
|
<a id="__codelineno-41-2" name="__codelineno-41-2" href="#__codelineno-41-2"></a><span class="nt">auth</span><span class="p">:</span>
|
|
<a id="__codelineno-41-3" name="__codelineno-41-3" href="#__codelineno-41-3"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-41-4" name="__codelineno-41-4" href="#__codelineno-41-4"></a><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">token</span><span class="w"> </span><span class="c1"># Token mode (default)</span>
|
|
<a id="__codelineno-41-5" name="__codelineno-41-5" href="#__codelineno-41-5"></a><span class="w"> </span><span class="nt">tokens</span><span class="p">:</span>
|
|
<a id="__codelineno-41-6" name="__codelineno-41-6" href="#__codelineno-41-6"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">d4f88f6d9292c10cc3e21c4aad56d2be485db532b54fe961d738e1137d247823</span>
|
|
<a id="__codelineno-41-7" name="__codelineno-41-7" href="#__codelineno-41-7"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">8803f621acc3898df1d7a8f514bc3602551a0681a8f747bd4e43c3c5849d57a7</span>
|
|
</code></pre></div>
|
|
<h4 id="step-2-generate-token-if-needed">Step 2: Generate Token (if needed)<a class="headerlink" href="#step-2-generate-token-if-needed" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a><span class="c1"># Generate a secure random token</span>
|
|
<a id="__codelineno-42-2" name="__codelineno-42-2" href="#__codelineno-42-2"></a>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span>
|
|
<a id="__codelineno-42-3" name="__codelineno-42-3" href="#__codelineno-42-3"></a>
|
|
<a id="__codelineno-42-4" name="__codelineno-42-4" href="#__codelineno-42-4"></a><span class="c1"># Or using Python</span>
|
|
<a id="__codelineno-42-5" name="__codelineno-42-5" href="#__codelineno-42-5"></a>python3<span class="w"> </span>-c<span class="w"> </span><span class="s2">"import secrets; print(secrets.token_hex(32))"</span>
|
|
<a id="__codelineno-42-6" name="__codelineno-42-6" href="#__codelineno-42-6"></a>
|
|
<a id="__codelineno-42-7" name="__codelineno-42-7" href="#__codelineno-42-7"></a><span class="c1"># Example output:</span>
|
|
<a id="__codelineno-42-8" name="__codelineno-42-8" href="#__codelineno-42-8"></a><span class="c1"># d4f88f6d9292c10cc3e21c4aad56d2be485db532b54fe961d738e1137d247823</span>
|
|
</code></pre></div>
|
|
<h4 id="step-3-deploy-application">Step 3: Deploy Application<a class="headerlink" href="#step-3-deploy-application" title="Permanent link">¶</a></h4>
|
|
<p>Commit and push your changes:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-43-1" name="__codelineno-43-1" href="#__codelineno-43-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/helm-prod-values
|
|
<a id="__codelineno-43-2" name="__codelineno-43-2" href="#__codelineno-43-2"></a>git<span class="w"> </span>add<span class="w"> </span>myapp/values.yaml
|
|
<a id="__codelineno-43-3" name="__codelineno-43-3" href="#__codelineno-43-3"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Enable token auth for myapp"</span>
|
|
<a id="__codelineno-43-4" name="__codelineno-43-4" href="#__codelineno-43-4"></a>git<span class="w"> </span>push
|
|
</code></pre></div></p>
|
|
<p>ArgoCD will sync, and the Kyverno policy will:
|
|
- Inject the auth sidecar container
|
|
- Create an <code>auth-tokens</code> Secret with your tokens
|
|
- Configure the sidecar to validate against these tokens</p>
|
|
<h4 id="step-4-access-application">Step 4: Access Application<a class="headerlink" href="#step-4-access-application" title="Permanent link">¶</a></h4>
|
|
<p>Use your token in the <code>Authorization</code> header:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-44-1" name="__codelineno-44-1" href="#__codelineno-44-1"></a><span class="c1"># Access application with token</span>
|
|
<a id="__codelineno-44-2" name="__codelineno-44-2" href="#__codelineno-44-2"></a>curl<span class="w"> </span>-H<span class="w"> </span><span class="s2">"Authorization: Bearer d4f88f6d9292c10cc3e21c4aad56d2be485db532b54fe961d738e1137d247823"</span><span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-44-3" name="__codelineno-44-3" href="#__codelineno-44-3"></a><span class="w"> </span>https://myapp.forteapps.net/api/data
|
|
<a id="__codelineno-44-4" name="__codelineno-44-4" href="#__codelineno-44-4"></a>
|
|
<a id="__codelineno-44-5" name="__codelineno-44-5" href="#__codelineno-44-5"></a><span class="c1"># Without token (will be rejected)</span>
|
|
<a id="__codelineno-44-6" name="__codelineno-44-6" href="#__codelineno-44-6"></a>curl<span class="w"> </span>https://myapp.forteapps.net/api/data
|
|
<a id="__codelineno-44-7" name="__codelineno-44-7" href="#__codelineno-44-7"></a><span class="c1"># Response: 401 Unauthorized</span>
|
|
</code></pre></div>
|
|
<h4 id="advanced-custom-secret-name">Advanced: Custom Secret Name<a class="headerlink" href="#advanced-custom-secret-name" title="Permanent link">¶</a></h4>
|
|
<p>To use a different secret for tokens:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-45-1" name="__codelineno-45-1" href="#__codelineno-45-1"></a><span class="c1"># In Helm values</span>
|
|
<a id="__codelineno-45-2" name="__codelineno-45-2" href="#__codelineno-45-2"></a><span class="nt">auth</span><span class="p">:</span>
|
|
<a id="__codelineno-45-3" name="__codelineno-45-3" href="#__codelineno-45-3"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-45-4" name="__codelineno-45-4" href="#__codelineno-45-4"></a><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">token</span>
|
|
<a id="__codelineno-45-5" name="__codelineno-45-5" href="#__codelineno-45-5"></a><span class="w"> </span><span class="nt">tokens</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[]</span><span class="w"> </span><span class="c1"># Empty - using external secret</span>
|
|
<a id="__codelineno-45-6" name="__codelineno-45-6" href="#__codelineno-45-6"></a>
|
|
<a id="__codelineno-45-7" name="__codelineno-45-7" href="#__codelineno-45-7"></a><span class="c1"># Tokens will be read from custom secret</span>
|
|
</code></pre></div>
|
|
<p>Then reference it via annotation (configured by Helm chart automatically):
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-46-1" name="__codelineno-46-1" href="#__codelineno-46-1"></a><span class="c1"># Helm chart sets this annotation:</span>
|
|
<a id="__codelineno-46-2" name="__codelineno-46-2" href="#__codelineno-46-2"></a><span class="nt">policies.forteapps.io/auth-token-secret-name</span><span class="p">:</span><span class="w"> </span><span class="s">"myapp-auth-tokens"</span>
|
|
</code></pre></div></p>
|
|
<p>Create the secret manually:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-47-1" name="__codelineno-47-1" href="#__codelineno-47-1"></a>kubectl<span class="w"> </span>create<span class="w"> </span>secret<span class="w"> </span>generic<span class="w"> </span>myapp-auth-tokens<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-47-2" name="__codelineno-47-2" href="#__codelineno-47-2"></a><span class="w"> </span>--from-file<span class="o">=</span><span class="nv">tokens</span><span class="o">=</span>tokens.txt<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-47-3" name="__codelineno-47-3" href="#__codelineno-47-3"></a><span class="w"> </span>--namespace<span class="o">=</span>myapp
|
|
</code></pre></div></p>
|
|
<hr />
|
|
<h3 id="oidc-authentication">OIDC Authentication<a class="headerlink" href="#oidc-authentication" title="Permanent link">¶</a></h3>
|
|
<p>OIDC mode integrates with identity providers like Keycloak, Okta, Auth0, Azure AD, etc.</p>
|
|
<h4 id="step-1-configure-identity-provider">Step 1: Configure Identity Provider<a class="headerlink" href="#step-1-configure-identity-provider" title="Permanent link">¶</a></h4>
|
|
<p>In your identity provider (e.g., Keycloak):
|
|
1. Create a new client (e.g., <code>myapp</code>)
|
|
2. Set redirect URI: <code>https://myapp.forteapps.net/auth/callback</code>
|
|
3. Note the <strong>Client ID</strong> and <strong>Client Secret</strong>
|
|
4. Note the <strong>Authority URL</strong> (e.g., <code>https://keycloak.forteapps.net/realms/master</code>)</p>
|
|
<h4 id="step-2-create-oidc-secret">Step 2: Create OIDC Secret<a class="headerlink" href="#step-2-create-oidc-secret" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-48-1" name="__codelineno-48-1" href="#__codelineno-48-1"></a><span class="c1"># Create plain secret</span>
|
|
<a id="__codelineno-48-2" name="__codelineno-48-2" href="#__codelineno-48-2"></a>kubectl<span class="w"> </span>create<span class="w"> </span>secret<span class="w"> </span>generic<span class="w"> </span>auth-oidc<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-48-3" name="__codelineno-48-3" href="#__codelineno-48-3"></a><span class="w"> </span>--from-literal<span class="o">=</span>client-secret<span class="o">=</span>your-oidc-client-secret<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-48-4" name="__codelineno-48-4" href="#__codelineno-48-4"></a><span class="w"> </span>--from-literal<span class="o">=</span>cookie-secret<span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span><span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-48-5" name="__codelineno-48-5" href="#__codelineno-48-5"></a><span class="w"> </span>--namespace<span class="o">=</span>myapp<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-48-6" name="__codelineno-48-6" href="#__codelineno-48-6"></a><span class="w"> </span>--dry-run<span class="o">=</span>client<span class="w"> </span>-o<span class="w"> </span>yaml<span class="w"> </span>><span class="w"> </span>private/myapp-auth-oidc.yaml
|
|
<a id="__codelineno-48-7" name="__codelineno-48-7" href="#__codelineno-48-7"></a>
|
|
<a id="__codelineno-48-8" name="__codelineno-48-8" href="#__codelineno-48-8"></a><span class="c1"># Seal it</span>
|
|
<a id="__codelineno-48-9" name="__codelineno-48-9" href="#__codelineno-48-9"></a>kubeseal<span class="w"> </span>--format<span class="o">=</span>yaml<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-48-10" name="__codelineno-48-10" href="#__codelineno-48-10"></a><span class="w"> </span>--cert<span class="o">=</span>pub-cert.pem<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-48-11" name="__codelineno-48-11" href="#__codelineno-48-11"></a><span class="w"> </span>--namespace<span class="o">=</span>myapp<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-48-12" name="__codelineno-48-12" href="#__codelineno-48-12"></a><span class="w"> </span><<span class="w"> </span>private/myapp-auth-oidc.yaml<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-48-13" name="__codelineno-48-13" href="#__codelineno-48-13"></a><span class="w"> </span>><span class="w"> </span>secrets/myapp-auth-oidc-sealed.yaml
|
|
<a id="__codelineno-48-14" name="__codelineno-48-14" href="#__codelineno-48-14"></a>
|
|
<a id="__codelineno-48-15" name="__codelineno-48-15" href="#__codelineno-48-15"></a><span class="c1"># Commit sealed secret</span>
|
|
<a id="__codelineno-48-16" name="__codelineno-48-16" href="#__codelineno-48-16"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/launchpad
|
|
<a id="__codelineno-48-17" name="__codelineno-48-17" href="#__codelineno-48-17"></a>git<span class="w"> </span>add<span class="w"> </span>secrets/myapp-auth-oidc-sealed.yaml
|
|
<a id="__codelineno-48-18" name="__codelineno-48-18" href="#__codelineno-48-18"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Add OIDC secrets for myapp"</span>
|
|
<a id="__codelineno-48-19" name="__codelineno-48-19" href="#__codelineno-48-19"></a>git<span class="w"> </span>push
|
|
<a id="__codelineno-48-20" name="__codelineno-48-20" href="#__codelineno-48-20"></a>
|
|
<a id="__codelineno-48-21" name="__codelineno-48-21" href="#__codelineno-48-21"></a><span class="c1"># Clean up</span>
|
|
<a id="__codelineno-48-22" name="__codelineno-48-22" href="#__codelineno-48-22"></a>rm<span class="w"> </span>private/myapp-auth-oidc.yaml
|
|
</code></pre></div>
|
|
<h4 id="step-3-configure-helm-values">Step 3: Configure Helm Values<a class="headerlink" href="#step-3-configure-helm-values" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-49-1" name="__codelineno-49-1" href="#__codelineno-49-1"></a><span class="c1"># In helm-values/myapp/values.yaml</span>
|
|
<a id="__codelineno-49-2" name="__codelineno-49-2" href="#__codelineno-49-2"></a><span class="nt">auth</span><span class="p">:</span>
|
|
<a id="__codelineno-49-3" name="__codelineno-49-3" href="#__codelineno-49-3"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-49-4" name="__codelineno-49-4" href="#__codelineno-49-4"></a><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">oidc</span><span class="w"> </span><span class="c1"># OIDC mode</span>
|
|
<a id="__codelineno-49-5" name="__codelineno-49-5" href="#__codelineno-49-5"></a><span class="w"> </span><span class="nt">oidc</span><span class="p">:</span>
|
|
<a id="__codelineno-49-6" name="__codelineno-49-6" href="#__codelineno-49-6"></a><span class="w"> </span><span class="nt">authority</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://keycloak.forteapps.net/realms/master</span>
|
|
<a id="__codelineno-49-7" name="__codelineno-49-7" href="#__codelineno-49-7"></a><span class="w"> </span><span class="nt">clientId</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">myapp</span>
|
|
<a id="__codelineno-49-8" name="__codelineno-49-8" href="#__codelineno-49-8"></a><span class="w"> </span><span class="nt">scopes</span><span class="p">:</span><span class="w"> </span><span class="s">"openid,profile,email"</span>
|
|
<a id="__codelineno-49-9" name="__codelineno-49-9" href="#__codelineno-49-9"></a><span class="w"> </span><span class="nt">callbackPath</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/auth/callback</span>
|
|
</code></pre></div>
|
|
<h4 id="step-4-deploy-application">Step 4: Deploy Application<a class="headerlink" href="#step-4-deploy-application" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-50-1" name="__codelineno-50-1" href="#__codelineno-50-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/helm-prod-values
|
|
<a id="__codelineno-50-2" name="__codelineno-50-2" href="#__codelineno-50-2"></a>git<span class="w"> </span>add<span class="w"> </span>myapp/values.yaml
|
|
<a id="__codelineno-50-3" name="__codelineno-50-3" href="#__codelineno-50-3"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Enable OIDC auth for myapp"</span>
|
|
<a id="__codelineno-50-4" name="__codelineno-50-4" href="#__codelineno-50-4"></a>git<span class="w"> </span>push
|
|
</code></pre></div>
|
|
<h4 id="step-5-access-application">Step 5: Access Application<a class="headerlink" href="#step-5-access-application" title="Permanent link">¶</a></h4>
|
|
<p>When users access <code>https://myapp.forteapps.net</code>:
|
|
1. They're redirected to the identity provider login page
|
|
2. After successful login, redirected back to <code>/auth/callback</code>
|
|
3. Session cookie is set
|
|
4. Subsequent requests are authenticated via cookie</p>
|
|
<p><strong>User flow</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-51-1" name="__codelineno-51-1" href="#__codelineno-51-1"></a>User → https://myapp.forteapps.net
|
|
<a id="__codelineno-51-2" name="__codelineno-51-2" href="#__codelineno-51-2"></a> ↓
|
|
<a id="__codelineno-51-3" name="__codelineno-51-3" href="#__codelineno-51-3"></a>Redirect → https://keycloak.forteapps.net/login
|
|
<a id="__codelineno-51-4" name="__codelineno-51-4" href="#__codelineno-51-4"></a> ↓
|
|
<a id="__codelineno-51-5" name="__codelineno-51-5" href="#__codelineno-51-5"></a>Login successful → Redirect with auth code
|
|
<a id="__codelineno-51-6" name="__codelineno-51-6" href="#__codelineno-51-6"></a> ↓
|
|
<a id="__codelineno-51-7" name="__codelineno-51-7" href="#__codelineno-51-7"></a>https://myapp.forteapps.net/auth/callback?code=xyz
|
|
<a id="__codelineno-51-8" name="__codelineno-51-8" href="#__codelineno-51-8"></a> ↓
|
|
<a id="__codelineno-51-9" name="__codelineno-51-9" href="#__codelineno-51-9"></a>Auth sidecar exchanges code for tokens
|
|
<a id="__codelineno-51-10" name="__codelineno-51-10" href="#__codelineno-51-10"></a> ↓
|
|
<a id="__codelineno-51-11" name="__codelineno-51-11" href="#__codelineno-51-11"></a>Sets session cookie
|
|
<a id="__codelineno-51-12" name="__codelineno-51-12" href="#__codelineno-51-12"></a> ↓
|
|
<a id="__codelineno-51-13" name="__codelineno-51-13" href="#__codelineno-51-13"></a>Redirects to application → https://myapp.forteapps.net
|
|
<a id="__codelineno-51-14" name="__codelineno-51-14" href="#__codelineno-51-14"></a> ↓
|
|
<a id="__codelineno-51-15" name="__codelineno-51-15" href="#__codelineno-51-15"></a>User sees application (authenticated)
|
|
</code></pre></div></p>
|
|
<hr />
|
|
<h3 id="authentication-configuration-reference">Authentication Configuration Reference<a class="headerlink" href="#authentication-configuration-reference" title="Permanent link">¶</a></h3>
|
|
<h4 id="helm-values-schema">Helm Values Schema<a class="headerlink" href="#helm-values-schema" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-52-1" name="__codelineno-52-1" href="#__codelineno-52-1"></a><span class="nt">auth</span><span class="p">:</span>
|
|
<a id="__codelineno-52-2" name="__codelineno-52-2" href="#__codelineno-52-2"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">false</span><span class="w"> </span><span class="c1"># Enable/disable authentication</span>
|
|
<a id="__codelineno-52-3" name="__codelineno-52-3" href="#__codelineno-52-3"></a><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">token</span><span class="w"> </span><span class="c1"># "token", "oidc", or "mcp"</span>
|
|
<a id="__codelineno-52-4" name="__codelineno-52-4" href="#__codelineno-52-4"></a>
|
|
<a id="__codelineno-52-5" name="__codelineno-52-5" href="#__codelineno-52-5"></a><span class="w"> </span><span class="c1"># Token mode configuration</span>
|
|
<a id="__codelineno-52-6" name="__codelineno-52-6" href="#__codelineno-52-6"></a><span class="w"> </span><span class="nt">tokens</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[]</span><span class="w"> </span><span class="c1"># List of valid bearer tokens</span>
|
|
<a id="__codelineno-52-7" name="__codelineno-52-7" href="#__codelineno-52-7"></a><span class="w"> </span><span class="c1"># - token1</span>
|
|
<a id="__codelineno-52-8" name="__codelineno-52-8" href="#__codelineno-52-8"></a><span class="w"> </span><span class="c1"># - token2</span>
|
|
<a id="__codelineno-52-9" name="__codelineno-52-9" href="#__codelineno-52-9"></a>
|
|
<a id="__codelineno-52-10" name="__codelineno-52-10" href="#__codelineno-52-10"></a><span class="w"> </span><span class="c1"># OIDC mode configuration</span>
|
|
<a id="__codelineno-52-11" name="__codelineno-52-11" href="#__codelineno-52-11"></a><span class="w"> </span><span class="nt">oidc</span><span class="p">:</span>
|
|
<a id="__codelineno-52-12" name="__codelineno-52-12" href="#__codelineno-52-12"></a><span class="w"> </span><span class="nt">authority</span><span class="p">:</span><span class="w"> </span><span class="s">""</span><span class="w"> </span><span class="c1"># OIDC provider URL (required for OIDC)</span>
|
|
<a id="__codelineno-52-13" name="__codelineno-52-13" href="#__codelineno-52-13"></a><span class="w"> </span><span class="nt">clientId</span><span class="p">:</span><span class="w"> </span><span class="s">""</span><span class="w"> </span><span class="c1"># OIDC client ID (required for OIDC)</span>
|
|
<a id="__codelineno-52-14" name="__codelineno-52-14" href="#__codelineno-52-14"></a><span class="w"> </span><span class="nt">scopes</span><span class="p">:</span><span class="w"> </span><span class="s">"openid,profile,email"</span><span class="w"> </span><span class="c1"># OIDC scopes (optional)</span>
|
|
<a id="__codelineno-52-15" name="__codelineno-52-15" href="#__codelineno-52-15"></a><span class="w"> </span><span class="nt">callbackPath</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/auth/callback</span><span class="w"> </span><span class="c1"># OAuth callback path (optional)</span>
|
|
<a id="__codelineno-52-16" name="__codelineno-52-16" href="#__codelineno-52-16"></a>
|
|
<a id="__codelineno-52-17" name="__codelineno-52-17" href="#__codelineno-52-17"></a><span class="w"> </span><span class="c1"># MCP mode configuration (RFC 9728 / RFC 7591)</span>
|
|
<a id="__codelineno-52-18" name="__codelineno-52-18" href="#__codelineno-52-18"></a><span class="w"> </span><span class="nt">mcp</span><span class="p">:</span>
|
|
<a id="__codelineno-52-19" name="__codelineno-52-19" href="#__codelineno-52-19"></a><span class="w"> </span><span class="nt">resource</span><span class="p">:</span><span class="w"> </span><span class="s">""</span><span class="w"> </span><span class="c1"># Protected resource URL (required for MCP)</span>
|
|
<a id="__codelineno-52-20" name="__codelineno-52-20" href="#__codelineno-52-20"></a><span class="w"> </span><span class="nt">authority</span><span class="p">:</span><span class="w"> </span><span class="s">""</span><span class="w"> </span><span class="c1"># Authorization server URL (required for MCP)</span>
|
|
<a id="__codelineno-52-21" name="__codelineno-52-21" href="#__codelineno-52-21"></a><span class="w"> </span><span class="nt">scopes</span><span class="p">:</span><span class="w"> </span><span class="s">"read,write"</span><span class="w"> </span><span class="c1"># Supported scopes (optional)</span>
|
|
</code></pre></div>
|
|
<h4 id="annotations-set-by-helm-chart">Annotations Set by Helm Chart<a class="headerlink" href="#annotations-set-by-helm-chart" title="Permanent link">¶</a></h4>
|
|
<p>When <code>auth.enabled: true</code>, the Helm chart sets these pod annotations:</p>
|
|
<p><strong>Token mode</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-53-1" name="__codelineno-53-1" href="#__codelineno-53-1"></a><span class="nt">policies.forteapps.io/auth</span><span class="p">:</span><span class="w"> </span><span class="s">"true"</span>
|
|
<a id="__codelineno-53-2" name="__codelineno-53-2" href="#__codelineno-53-2"></a><span class="nt">policies.forteapps.io/auth-type</span><span class="p">:</span><span class="w"> </span><span class="s">"token"</span>
|
|
<a id="__codelineno-53-3" name="__codelineno-53-3" href="#__codelineno-53-3"></a><span class="nt">policies.forteapps.io/auth-token-secret-name</span><span class="p">:</span><span class="w"> </span><span class="s">"auth-tokens"</span>
|
|
<a id="__codelineno-53-4" name="__codelineno-53-4" href="#__codelineno-53-4"></a><span class="nt">policies.forteapps.io/auth-upstream-url</span><span class="p">:</span><span class="w"> </span><span class="s">"http://localhost:3000"</span>
|
|
</code></pre></div></p>
|
|
<p><strong>OIDC mode</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-54-1" name="__codelineno-54-1" href="#__codelineno-54-1"></a><span class="nt">policies.forteapps.io/auth</span><span class="p">:</span><span class="w"> </span><span class="s">"true"</span>
|
|
<a id="__codelineno-54-2" name="__codelineno-54-2" href="#__codelineno-54-2"></a><span class="nt">policies.forteapps.io/auth-type</span><span class="p">:</span><span class="w"> </span><span class="s">"oidc"</span>
|
|
<a id="__codelineno-54-3" name="__codelineno-54-3" href="#__codelineno-54-3"></a><span class="nt">policies.forteapps.io/auth-oidc-authority</span><span class="p">:</span><span class="w"> </span><span class="s">"https://keycloak.forteapps.net/realms/master"</span>
|
|
<a id="__codelineno-54-4" name="__codelineno-54-4" href="#__codelineno-54-4"></a><span class="nt">policies.forteapps.io/auth-oidc-client-id</span><span class="p">:</span><span class="w"> </span><span class="s">"myapp"</span>
|
|
<a id="__codelineno-54-5" name="__codelineno-54-5" href="#__codelineno-54-5"></a><span class="nt">policies.forteapps.io/auth-oidc-scopes</span><span class="p">:</span><span class="w"> </span><span class="s">"openid,profile,email"</span>
|
|
<a id="__codelineno-54-6" name="__codelineno-54-6" href="#__codelineno-54-6"></a><span class="nt">policies.forteapps.io/auth-oidc-callback-path</span><span class="p">:</span><span class="w"> </span><span class="s">"/auth/callback"</span>
|
|
<a id="__codelineno-54-7" name="__codelineno-54-7" href="#__codelineno-54-7"></a><span class="nt">policies.forteapps.io/auth-upstream-url</span><span class="p">:</span><span class="w"> </span><span class="s">"http://localhost:3000"</span>
|
|
</code></pre></div></p>
|
|
<p><strong>MCP mode</strong> (OAuth 2.0 for MCP servers):
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-55-1" name="__codelineno-55-1" href="#__codelineno-55-1"></a><span class="nt">policies.forteapps.io/auth</span><span class="p">:</span><span class="w"> </span><span class="s">"true"</span>
|
|
<a id="__codelineno-55-2" name="__codelineno-55-2" href="#__codelineno-55-2"></a><span class="nt">policies.forteapps.io/auth-type</span><span class="p">:</span><span class="w"> </span><span class="s">"mcp"</span>
|
|
<a id="__codelineno-55-3" name="__codelineno-55-3" href="#__codelineno-55-3"></a><span class="nt">policies.forteapps.io/auth-mcp-resource</span><span class="p">:</span><span class="w"> </span><span class="s">"https://mcp.forteapps.net"</span>
|
|
<a id="__codelineno-55-4" name="__codelineno-55-4" href="#__codelineno-55-4"></a><span class="nt">policies.forteapps.io/auth-mcp-authority</span><span class="p">:</span><span class="w"> </span><span class="s">"https://keycloak.forteapps.net/realms/master"</span>
|
|
<a id="__codelineno-55-5" name="__codelineno-55-5" href="#__codelineno-55-5"></a><span class="nt">policies.forteapps.io/auth-mcp-scopes</span><span class="p">:</span><span class="w"> </span><span class="s">"read,write"</span>
|
|
<a id="__codelineno-55-6" name="__codelineno-55-6" href="#__codelineno-55-6"></a><span class="nt">policies.forteapps.io/auth-upstream-url</span><span class="p">:</span><span class="w"> </span><span class="s">"http://localhost:3000"</span>
|
|
</code></pre></div></p>
|
|
<h4 id="sidecar-configuration">Sidecar Configuration<a class="headerlink" href="#sidecar-configuration" title="Permanent link">¶</a></h4>
|
|
<p>The auth sidecar container:
|
|
- <strong>Image</strong>: <code>ghcr.io/fortedigital/auth-sidecar:latest</code>
|
|
- <strong>Port</strong>: 8080
|
|
- <strong>Resources</strong>: 10m CPU / 32Mi memory (requests), 50m CPU / 64Mi memory (limits)
|
|
- <strong>Health checks</strong>: <code>/healthz</code> endpoint
|
|
- <strong>Security</strong>: Read-only root filesystem, no privilege escalation</p>
|
|
<h4 id="advanced-custom-sidecar-image">Advanced: Custom Sidecar Image<a class="headerlink" href="#advanced-custom-sidecar-image" title="Permanent link">¶</a></h4>
|
|
<p>To use a different auth sidecar image:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-56-1" name="__codelineno-56-1" href="#__codelineno-56-1"></a><span class="c1"># These annotations can be set in the Helm chart template if needed</span>
|
|
<a id="__codelineno-56-2" name="__codelineno-56-2" href="#__codelineno-56-2"></a><span class="nt">policies.forteapps.io/auth-image</span><span class="p">:</span><span class="w"> </span><span class="s">"your-registry/your-auth-proxy"</span>
|
|
<a id="__codelineno-56-3" name="__codelineno-56-3" href="#__codelineno-56-3"></a><span class="nt">policies.forteapps.io/auth-image-version</span><span class="p">:</span><span class="w"> </span><span class="s">"v1.2.3"</span>
|
|
</code></pre></div>
|
|
<hr />
|
|
<h3 id="authentication-examples">Authentication Examples<a class="headerlink" href="#authentication-examples" title="Permanent link">¶</a></h3>
|
|
<h4 id="example-1-internal-api-with-token-auth">Example 1: Internal API with Token Auth<a class="headerlink" href="#example-1-internal-api-with-token-auth" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-57-1" name="__codelineno-57-1" href="#__codelineno-57-1"></a><span class="c1"># helm-values/internal-api/values.yaml</span>
|
|
<a id="__codelineno-57-2" name="__codelineno-57-2" href="#__codelineno-57-2"></a><span class="nt">app</span><span class="p">:</span>
|
|
<a id="__codelineno-57-3" name="__codelineno-57-3" href="#__codelineno-57-3"></a><span class="w"> </span><span class="nt">image</span><span class="p">:</span>
|
|
<a id="__codelineno-57-4" name="__codelineno-57-4" href="#__codelineno-57-4"></a><span class="w"> </span><span class="nt">repository</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">ghcr.io/company/internal-api</span>
|
|
<a id="__codelineno-57-5" name="__codelineno-57-5" href="#__codelineno-57-5"></a><span class="w"> </span><span class="nt">tag</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1.0.0</span>
|
|
<a id="__codelineno-57-6" name="__codelineno-57-6" href="#__codelineno-57-6"></a>
|
|
<a id="__codelineno-57-7" name="__codelineno-57-7" href="#__codelineno-57-7"></a><span class="nt">auth</span><span class="p">:</span>
|
|
<a id="__codelineno-57-8" name="__codelineno-57-8" href="#__codelineno-57-8"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-57-9" name="__codelineno-57-9" href="#__codelineno-57-9"></a><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">token</span>
|
|
<a id="__codelineno-57-10" name="__codelineno-57-10" href="#__codelineno-57-10"></a><span class="w"> </span><span class="nt">tokens</span><span class="p">:</span>
|
|
<a id="__codelineno-57-11" name="__codelineno-57-11" href="#__codelineno-57-11"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">d4f88f6d9292c10cc3e21c4aad56d2be485db532b54fe961d738e1137d247823</span><span class="w"> </span><span class="c1"># Service A</span>
|
|
<a id="__codelineno-57-12" name="__codelineno-57-12" href="#__codelineno-57-12"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">8803f621acc3898df1d7a8f514bc3602551a0681a8f747bd4e43c3c5849d57a7</span><span class="w"> </span><span class="c1"># Service B</span>
|
|
<a id="__codelineno-57-13" name="__codelineno-57-13" href="#__codelineno-57-13"></a>
|
|
<a id="__codelineno-57-14" name="__codelineno-57-14" href="#__codelineno-57-14"></a><span class="nt">ingress</span><span class="p">:</span>
|
|
<a id="__codelineno-57-15" name="__codelineno-57-15" href="#__codelineno-57-15"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-57-16" name="__codelineno-57-16" href="#__codelineno-57-16"></a><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">internal-api.forteapps.net</span>
|
|
</code></pre></div>
|
|
<p><strong>Usage</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-58-1" name="__codelineno-58-1" href="#__codelineno-58-1"></a><span class="c1"># Service A calls API</span>
|
|
<a id="__codelineno-58-2" name="__codelineno-58-2" href="#__codelineno-58-2"></a>curl<span class="w"> </span>-H<span class="w"> </span><span class="s2">"Authorization: Bearer d4f88f..."</span><span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-58-3" name="__codelineno-58-3" href="#__codelineno-58-3"></a><span class="w"> </span>https://internal-api.forteapps.net/api/endpoint
|
|
</code></pre></div></p>
|
|
<h4 id="example-2-user-facing-app-with-oidc">Example 2: User-Facing App with OIDC<a class="headerlink" href="#example-2-user-facing-app-with-oidc" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-59-1" name="__codelineno-59-1" href="#__codelineno-59-1"></a><span class="c1"># helm-values/web-app/values.yaml</span>
|
|
<a id="__codelineno-59-2" name="__codelineno-59-2" href="#__codelineno-59-2"></a><span class="nt">app</span><span class="p">:</span>
|
|
<a id="__codelineno-59-3" name="__codelineno-59-3" href="#__codelineno-59-3"></a><span class="w"> </span><span class="nt">image</span><span class="p">:</span>
|
|
<a id="__codelineno-59-4" name="__codelineno-59-4" href="#__codelineno-59-4"></a><span class="w"> </span><span class="nt">repository</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">ghcr.io/company/web-app</span>
|
|
<a id="__codelineno-59-5" name="__codelineno-59-5" href="#__codelineno-59-5"></a><span class="w"> </span><span class="nt">tag</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v2.1.0</span>
|
|
<a id="__codelineno-59-6" name="__codelineno-59-6" href="#__codelineno-59-6"></a>
|
|
<a id="__codelineno-59-7" name="__codelineno-59-7" href="#__codelineno-59-7"></a><span class="nt">auth</span><span class="p">:</span>
|
|
<a id="__codelineno-59-8" name="__codelineno-59-8" href="#__codelineno-59-8"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-59-9" name="__codelineno-59-9" href="#__codelineno-59-9"></a><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">oidc</span>
|
|
<a id="__codelineno-59-10" name="__codelineno-59-10" href="#__codelineno-59-10"></a><span class="w"> </span><span class="nt">oidc</span><span class="p">:</span>
|
|
<a id="__codelineno-59-11" name="__codelineno-59-11" href="#__codelineno-59-11"></a><span class="w"> </span><span class="nt">authority</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://auth.company.com/realms/employees</span>
|
|
<a id="__codelineno-59-12" name="__codelineno-59-12" href="#__codelineno-59-12"></a><span class="w"> </span><span class="nt">clientId</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">web-app-prod</span>
|
|
<a id="__codelineno-59-13" name="__codelineno-59-13" href="#__codelineno-59-13"></a><span class="w"> </span><span class="nt">scopes</span><span class="p">:</span><span class="w"> </span><span class="s">"openid,profile,email,groups"</span>
|
|
<a id="__codelineno-59-14" name="__codelineno-59-14" href="#__codelineno-59-14"></a><span class="w"> </span><span class="nt">callbackPath</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/auth/callback</span>
|
|
<a id="__codelineno-59-15" name="__codelineno-59-15" href="#__codelineno-59-15"></a>
|
|
<a id="__codelineno-59-16" name="__codelineno-59-16" href="#__codelineno-59-16"></a><span class="nt">ingress</span><span class="p">:</span>
|
|
<a id="__codelineno-59-17" name="__codelineno-59-17" href="#__codelineno-59-17"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-59-18" name="__codelineno-59-18" href="#__codelineno-59-18"></a><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">web-app.forteapps.net</span>
|
|
</code></pre></div>
|
|
<p><strong>With sealed OIDC secret</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-60-1" name="__codelineno-60-1" href="#__codelineno-60-1"></a><span class="c1"># Create and seal secret</span>
|
|
<a id="__codelineno-60-2" name="__codelineno-60-2" href="#__codelineno-60-2"></a>kubectl<span class="w"> </span>create<span class="w"> </span>secret<span class="w"> </span>generic<span class="w"> </span>auth-oidc<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-60-3" name="__codelineno-60-3" href="#__codelineno-60-3"></a><span class="w"> </span>--from-literal<span class="o">=</span>client-secret<span class="o">=</span>super-secret-value<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-60-4" name="__codelineno-60-4" href="#__codelineno-60-4"></a><span class="w"> </span>--from-literal<span class="o">=</span>cookie-secret<span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span><span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-60-5" name="__codelineno-60-5" href="#__codelineno-60-5"></a><span class="w"> </span>--namespace<span class="o">=</span>web-app<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-60-6" name="__codelineno-60-6" href="#__codelineno-60-6"></a><span class="w"> </span>--dry-run<span class="o">=</span>client<span class="w"> </span>-o<span class="w"> </span>yaml<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-60-7" name="__codelineno-60-7" href="#__codelineno-60-7"></a><span class="w"> </span>kubeseal<span class="w"> </span>--format<span class="o">=</span>yaml<span class="w"> </span>--cert<span class="o">=</span>pub-cert.pem<span class="w"> </span>--namespace<span class="o">=</span>web-app<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-60-8" name="__codelineno-60-8" href="#__codelineno-60-8"></a><span class="w"> </span>><span class="w"> </span>secrets/web-app-auth-oidc-sealed.yaml
|
|
</code></pre></div></p>
|
|
<h4 id="example-3-mcp-server-with-oauth-20">Example 3: MCP Server with OAuth 2.0<a class="headerlink" href="#example-3-mcp-server-with-oauth-20" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-61-1" name="__codelineno-61-1" href="#__codelineno-61-1"></a><span class="c1"># helm-values/mcp-server/values.yaml</span>
|
|
<a id="__codelineno-61-2" name="__codelineno-61-2" href="#__codelineno-61-2"></a><span class="nt">app</span><span class="p">:</span>
|
|
<a id="__codelineno-61-3" name="__codelineno-61-3" href="#__codelineno-61-3"></a><span class="w"> </span><span class="nt">image</span><span class="p">:</span>
|
|
<a id="__codelineno-61-4" name="__codelineno-61-4" href="#__codelineno-61-4"></a><span class="w"> </span><span class="nt">repository</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">ghcr.io/company/mcp-server</span>
|
|
<a id="__codelineno-61-5" name="__codelineno-61-5" href="#__codelineno-61-5"></a><span class="w"> </span><span class="nt">tag</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1.0.0</span>
|
|
<a id="__codelineno-61-6" name="__codelineno-61-6" href="#__codelineno-61-6"></a>
|
|
<a id="__codelineno-61-7" name="__codelineno-61-7" href="#__codelineno-61-7"></a><span class="nt">auth</span><span class="p">:</span>
|
|
<a id="__codelineno-61-8" name="__codelineno-61-8" href="#__codelineno-61-8"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-61-9" name="__codelineno-61-9" href="#__codelineno-61-9"></a><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">mcp</span>
|
|
<a id="__codelineno-61-10" name="__codelineno-61-10" href="#__codelineno-61-10"></a><span class="w"> </span><span class="nt">mcp</span><span class="p">:</span>
|
|
<a id="__codelineno-61-11" name="__codelineno-61-11" href="#__codelineno-61-11"></a><span class="w"> </span><span class="nt">resource</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://mcp-server.forteapps.net</span>
|
|
<a id="__codelineno-61-12" name="__codelineno-61-12" href="#__codelineno-61-12"></a><span class="w"> </span><span class="nt">authority</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://auth.company.com/realms/mcp</span>
|
|
<a id="__codelineno-61-13" name="__codelineno-61-13" href="#__codelineno-61-13"></a><span class="w"> </span><span class="nt">scopes</span><span class="p">:</span><span class="w"> </span><span class="s">"read,write,admin"</span>
|
|
<a id="__codelineno-61-14" name="__codelineno-61-14" href="#__codelineno-61-14"></a>
|
|
<a id="__codelineno-61-15" name="__codelineno-61-15" href="#__codelineno-61-15"></a><span class="nt">ingress</span><span class="p">:</span>
|
|
<a id="__codelineno-61-16" name="__codelineno-61-16" href="#__codelineno-61-16"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-61-17" name="__codelineno-61-17" href="#__codelineno-61-17"></a><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">mcp-server.forteapps.net</span>
|
|
</code></pre></div>
|
|
<p>The MCP auth mode implements RFC 9728 (OAuth 2.0 Protected Resource Metadata) for authorization server discovery and RFC 7591 (OAuth 2.0 Dynamic Client Registration) for automatic client registration. MCP clients discover the authorization server and scopes from the <code>/.well-known/oauth-protected-resource</code> endpoint served by the sidecar.</p>
|
|
<h4 id="example-4-disabling-authentication">Example 4: Disabling Authentication<a class="headerlink" href="#example-4-disabling-authentication" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-62-1" name="__codelineno-62-1" href="#__codelineno-62-1"></a><span class="c1"># helm-values/public-api/values.yaml</span>
|
|
<a id="__codelineno-62-2" name="__codelineno-62-2" href="#__codelineno-62-2"></a><span class="nt">auth</span><span class="p">:</span>
|
|
<a id="__codelineno-62-3" name="__codelineno-62-3" href="#__codelineno-62-3"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">false</span><span class="w"> </span><span class="c1"># No authentication</span>
|
|
<a id="__codelineno-62-4" name="__codelineno-62-4" href="#__codelineno-62-4"></a>
|
|
<a id="__codelineno-62-5" name="__codelineno-62-5" href="#__codelineno-62-5"></a><span class="nt">ingress</span><span class="p">:</span>
|
|
<a id="__codelineno-62-6" name="__codelineno-62-6" href="#__codelineno-62-6"></a><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
|
|
<a id="__codelineno-62-7" name="__codelineno-62-7" href="#__codelineno-62-7"></a><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">public-api.forteapps.net</span>
|
|
</code></pre></div>
|
|
<hr />
|
|
<h3 id="troubleshooting-authentication">Troubleshooting Authentication<a class="headerlink" href="#troubleshooting-authentication" title="Permanent link">¶</a></h3>
|
|
<h4 id="issue-401-unauthorized-token-mode">Issue: 401 Unauthorized (Token Mode)<a class="headerlink" href="#issue-401-unauthorized-token-mode" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check token validity</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-63-1" name="__codelineno-63-1" href="#__codelineno-63-1"></a><span class="c1"># Get auth-tokens secret</span>
|
|
<a id="__codelineno-63-2" name="__codelineno-63-2" href="#__codelineno-63-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secret<span class="w"> </span>auth-tokens<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span>-o<span class="w"> </span>yaml
|
|
<a id="__codelineno-63-3" name="__codelineno-63-3" href="#__codelineno-63-3"></a>
|
|
<a id="__codelineno-63-4" name="__codelineno-63-4" href="#__codelineno-63-4"></a><span class="c1"># Decode tokens</span>
|
|
<a id="__codelineno-63-5" name="__codelineno-63-5" href="#__codelineno-63-5"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secret<span class="w"> </span>auth-tokens<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-63-6" name="__codelineno-63-6" href="#__codelineno-63-6"></a><span class="w"> </span>-o<span class="w"> </span><span class="nv">jsonpath</span><span class="o">=</span><span class="s1">'{.data.tokens}'</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>base64<span class="w"> </span>-d
|
|
<a id="__codelineno-63-7" name="__codelineno-63-7" href="#__codelineno-63-7"></a>
|
|
<a id="__codelineno-63-8" name="__codelineno-63-8" href="#__codelineno-63-8"></a><span class="c1"># Verify your token is in the list</span>
|
|
</code></pre></div></p>
|
|
<p><strong>Test with different token</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-64-1" name="__codelineno-64-1" href="#__codelineno-64-1"></a>curl<span class="w"> </span>-v<span class="w"> </span>-H<span class="w"> </span><span class="s2">"Authorization: Bearer YOUR-TOKEN-HERE"</span><span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-64-2" name="__codelineno-64-2" href="#__codelineno-64-2"></a><span class="w"> </span>https://myapp.forteapps.net/
|
|
</code></pre></div></p>
|
|
<h4 id="issue-oidc-login-loop">Issue: OIDC Login Loop<a class="headerlink" href="#issue-oidc-login-loop" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check OIDC configuration</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-65-1" name="__codelineno-65-1" href="#__codelineno-65-1"></a><span class="c1"># Verify auth-oidc secret exists</span>
|
|
<a id="__codelineno-65-2" name="__codelineno-65-2" href="#__codelineno-65-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secret<span class="w"> </span>auth-oidc<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-65-3" name="__codelineno-65-3" href="#__codelineno-65-3"></a>
|
|
<a id="__codelineno-65-4" name="__codelineno-65-4" href="#__codelineno-65-4"></a><span class="c1"># Check sidecar logs</span>
|
|
<a id="__codelineno-65-5" name="__codelineno-65-5" href="#__codelineno-65-5"></a>kubectl<span class="w"> </span>logs<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span><pod-name><span class="w"> </span>-c<span class="w"> </span>authn
|
|
<a id="__codelineno-65-6" name="__codelineno-65-6" href="#__codelineno-65-6"></a>
|
|
<a id="__codelineno-65-7" name="__codelineno-65-7" href="#__codelineno-65-7"></a><span class="c1"># Common issues:</span>
|
|
<a id="__codelineno-65-8" name="__codelineno-65-8" href="#__codelineno-65-8"></a><span class="c1"># - Wrong authority URL</span>
|
|
<a id="__codelineno-65-9" name="__codelineno-65-9" href="#__codelineno-65-9"></a><span class="c1"># - Wrong client ID</span>
|
|
<a id="__codelineno-65-10" name="__codelineno-65-10" href="#__codelineno-65-10"></a><span class="c1"># - Missing client-secret in auth-oidc Secret</span>
|
|
<a id="__codelineno-65-11" name="__codelineno-65-11" href="#__codelineno-65-11"></a><span class="c1"># - Redirect URI not configured in identity provider</span>
|
|
</code></pre></div></p>
|
|
<p><strong>Verify redirect URI</strong> in your identity provider matches:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-66-1" name="__codelineno-66-1" href="#__codelineno-66-1"></a>https://<your-app-domain>/auth/callback
|
|
</code></pre></div></p>
|
|
<h4 id="issue-auth-sidecar-not-injected">Issue: Auth Sidecar Not Injected<a class="headerlink" href="#issue-auth-sidecar-not-injected" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check pod annotations</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-67-1" name="__codelineno-67-1" href="#__codelineno-67-1"></a>kubectl<span class="w"> </span>get<span class="w"> </span>pod<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span><pod-name><span class="w"> </span>-o<span class="w"> </span>yaml<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>policies.forteapps.io
|
|
<a id="__codelineno-67-2" name="__codelineno-67-2" href="#__codelineno-67-2"></a>
|
|
<a id="__codelineno-67-3" name="__codelineno-67-3" href="#__codelineno-67-3"></a><span class="c1"># Should show:</span>
|
|
<a id="__codelineno-67-4" name="__codelineno-67-4" href="#__codelineno-67-4"></a><span class="c1"># policies.forteapps.io/auth: "true"</span>
|
|
</code></pre></div></p>
|
|
<p><strong>Check Kyverno policy</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-68-1" name="__codelineno-68-1" href="#__codelineno-68-1"></a>kubectl<span class="w"> </span>get<span class="w"> </span>clusterpolicy<span class="w"> </span>inject-auth-sidecar
|
|
<a id="__codelineno-68-2" name="__codelineno-68-2" href="#__codelineno-68-2"></a>kubectl<span class="w"> </span>describe<span class="w"> </span>clusterpolicy<span class="w"> </span>inject-auth-sidecar
|
|
</code></pre></div></p>
|
|
<p><strong>Check Kyverno logs</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-69-1" name="__codelineno-69-1" href="#__codelineno-69-1"></a>kubectl<span class="w"> </span>logs<span class="w"> </span>-n<span class="w"> </span>kyverno<span class="w"> </span>deployment/kyverno<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>inject-auth
|
|
</code></pre></div></p>
|
|
<h4 id="issue-auth-sidecar-crashes">Issue: Auth Sidecar Crashes<a class="headerlink" href="#issue-auth-sidecar-crashes" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check sidecar logs</strong>:
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-70-1" name="__codelineno-70-1" href="#__codelineno-70-1"></a>kubectl<span class="w"> </span>logs<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span><pod-name><span class="w"> </span>-c<span class="w"> </span>authn
|
|
</code></pre></div></p>
|
|
<p><strong>Common causes</strong>:
|
|
- Missing secret (auth-tokens or auth-oidc)
|
|
- Invalid OIDC configuration
|
|
- Can't reach OIDC authority URL
|
|
- Network policy blocking outbound OIDC requests</p>
|
|
<hr />
|
|
<h3 id="authentication-best-practices">Authentication Best Practices<a class="headerlink" href="#authentication-best-practices" title="Permanent link">¶</a></h3>
|
|
<p>✅ <strong>DO</strong>:
|
|
- Use OIDC for user-facing applications
|
|
- Use token auth for service-to-service communication
|
|
- Rotate tokens and secrets regularly
|
|
- Use strong random tokens (32+ bytes)
|
|
- Store client secrets in SealedSecrets
|
|
- Test authentication before deploying to production
|
|
- Document which tokens/users have access</p>
|
|
<p>❌ <strong>DON'T</strong>:
|
|
- Share tokens between environments
|
|
- Commit tokens to application code
|
|
- Use predictable tokens
|
|
- Reuse tokens across multiple applications
|
|
- Disable authentication on sensitive APIs
|
|
- Log tokens or secrets</p>
|
|
<hr />
|
|
<h2 id="adding-a-new-keycloak-client">Adding a New Keycloak Client<a class="headerlink" href="#adding-a-new-keycloak-client" title="Permanent link">¶</a></h2>
|
|
<p>There are two ways to add an OIDC client, depending on your use case:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Method</th>
|
|
<th>Best for</th>
|
|
<th>Who edits the infra repo?</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Self-service</strong> (recommended)</td>
|
|
<td>New apps that deploy their own resources</td>
|
|
<td>App developer — no infra changes needed</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Legacy (realm JSON)</strong></td>
|
|
<td>Existing clients already defined in forte-realm.json (e.g., Gitea)</td>
|
|
<td>Platform engineer</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Both methods are served by the <strong>Keycloak Client Registrar</strong> CronJob, which runs every 2 minutes.</p>
|
|
<h3 id="self-service-oidc-client-registration">Self-Service OIDC Client Registration<a class="headerlink" href="#self-service-oidc-client-registration" title="Permanent link">¶</a></h3>
|
|
<p>This is the recommended flow for new applications. Your app deploys a labeled config Secret in its own namespace; the platform handles everything else.</p>
|
|
<h4 id="how-it-works_1">How It Works<a class="headerlink" href="#how-it-works_1" title="Permanent link">¶</a></h4>
|
|
<ol>
|
|
<li>You deploy a Secret with label <code>keycloak.forteapps.net/client-config: "true"</code> containing a <code>client.json</code> definition</li>
|
|
<li>A <strong>Kyverno ClusterPolicy</strong> (<code>keycloak-client-config-cloner</code>) clones it to the <code>keycloak</code> namespace</li>
|
|
<li>The <strong>Client Registrar CronJob</strong> picks it up within 2 minutes:</li>
|
|
<li>Registers (or updates) the client in Keycloak</li>
|
|
<li>Fetches the auto-generated client secret</li>
|
|
<li>Creates a credential Secret in your app's namespace</li>
|
|
<li>Annotates the config Secret with sync status</li>
|
|
</ol>
|
|
<h4 id="step-1-create-the-config-secret">Step 1: Create the Config Secret<a class="headerlink" href="#step-1-create-the-config-secret" title="Permanent link">¶</a></h4>
|
|
<p>Deploy this Secret in your application's namespace (e.g., as part of your Helm chart or Kustomize overlay):</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-71-1" name="__codelineno-71-1" href="#__codelineno-71-1"></a><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1</span>
|
|
<a id="__codelineno-71-2" name="__codelineno-71-2" href="#__codelineno-71-2"></a><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Secret</span>
|
|
<a id="__codelineno-71-3" name="__codelineno-71-3" href="#__codelineno-71-3"></a><span class="nt">metadata</span><span class="p">:</span>
|
|
<a id="__codelineno-71-4" name="__codelineno-71-4" href="#__codelineno-71-4"></a><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">keycloak-client-myapp</span>
|
|
<a id="__codelineno-71-5" name="__codelineno-71-5" href="#__codelineno-71-5"></a><span class="w"> </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">myapp</span>
|
|
<a id="__codelineno-71-6" name="__codelineno-71-6" href="#__codelineno-71-6"></a><span class="w"> </span><span class="nt">labels</span><span class="p">:</span>
|
|
<a id="__codelineno-71-7" name="__codelineno-71-7" href="#__codelineno-71-7"></a><span class="w"> </span><span class="nt">keycloak.forteapps.net/client-config</span><span class="p">:</span><span class="w"> </span><span class="s">"true"</span>
|
|
<a id="__codelineno-71-8" name="__codelineno-71-8" href="#__codelineno-71-8"></a><span class="nt">stringData</span><span class="p">:</span>
|
|
<a id="__codelineno-71-9" name="__codelineno-71-9" href="#__codelineno-71-9"></a><span class="w"> </span><span class="nt">client.json</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">|</span>
|
|
<a id="__codelineno-71-10" name="__codelineno-71-10" href="#__codelineno-71-10"></a><span class="w"> </span><span class="no">{</span>
|
|
<a id="__codelineno-71-11" name="__codelineno-71-11" href="#__codelineno-71-11"></a><span class="w"> </span><span class="no">"clientId": "myapp",</span>
|
|
<a id="__codelineno-71-12" name="__codelineno-71-12" href="#__codelineno-71-12"></a><span class="w"> </span><span class="no">"name": "My Application",</span>
|
|
<a id="__codelineno-71-13" name="__codelineno-71-13" href="#__codelineno-71-13"></a><span class="w"> </span><span class="no">"redirectUris": ["https://myapp.forteapps.net/*"],</span>
|
|
<a id="__codelineno-71-14" name="__codelineno-71-14" href="#__codelineno-71-14"></a><span class="w"> </span><span class="no">"webOrigins": ["https://myapp.forteapps.net"],</span>
|
|
<a id="__codelineno-71-15" name="__codelineno-71-15" href="#__codelineno-71-15"></a><span class="w"> </span><span class="no">"defaultClientScopes": ["openid", "email", "profile"],</span>
|
|
<a id="__codelineno-71-16" name="__codelineno-71-16" href="#__codelineno-71-16"></a><span class="w"> </span><span class="no">"protocolMappers": [],</span>
|
|
<a id="__codelineno-71-17" name="__codelineno-71-17" href="#__codelineno-71-17"></a><span class="w"> </span><span class="no">"secret": {</span>
|
|
<a id="__codelineno-71-18" name="__codelineno-71-18" href="#__codelineno-71-18"></a><span class="w"> </span><span class="no">"namespace": "myapp",</span>
|
|
<a id="__codelineno-71-19" name="__codelineno-71-19" href="#__codelineno-71-19"></a><span class="w"> </span><span class="no">"name": "myapp-oidc-credentials",</span>
|
|
<a id="__codelineno-71-20" name="__codelineno-71-20" href="#__codelineno-71-20"></a><span class="w"> </span><span class="no">"keys": { "clientId": "client-id", "clientSecret": "client-secret" }</span>
|
|
<a id="__codelineno-71-21" name="__codelineno-71-21" href="#__codelineno-71-21"></a><span class="w"> </span><span class="no">}</span>
|
|
<a id="__codelineno-71-22" name="__codelineno-71-22" href="#__codelineno-71-22"></a><span class="w"> </span><span class="no">}</span>
|
|
</code></pre></div>
|
|
<p><strong><code>client.json</code> fields</strong>:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Field</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>clientId</code></td>
|
|
<td>Yes</td>
|
|
<td>Keycloak client ID</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>name</code></td>
|
|
<td>Yes</td>
|
|
<td>Display name in Keycloak</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>redirectUris</code></td>
|
|
<td>Yes</td>
|
|
<td>Allowed redirect URIs</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>webOrigins</code></td>
|
|
<td>Yes</td>
|
|
<td>Allowed web origins (CORS)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>defaultClientScopes</code></td>
|
|
<td>No</td>
|
|
<td>Scopes (default: <code>["openid", "email", "profile"]</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>protocolMappers</code></td>
|
|
<td>No</td>
|
|
<td>Custom claim mappers (default: <code>[]</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>secret.namespace</code></td>
|
|
<td>No</td>
|
|
<td>Namespace for the credential Secret (default: source namespace)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>secret.name</code></td>
|
|
<td>No</td>
|
|
<td>Name of the credential Secret (default: <code><clientId>-oidc-credentials</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>secret.keys.clientId</code></td>
|
|
<td>No</td>
|
|
<td>Key name for client ID in credential Secret (default: <code>client-id</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>secret.keys.clientSecret</code></td>
|
|
<td>No</td>
|
|
<td>Key name for client secret in credential Secret (default: <code>client-secret</code>)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h4 id="step-2-reference-the-credential-secret">Step 2: Reference the Credential Secret<a class="headerlink" href="#step-2-reference-the-credential-secret" title="Permanent link">¶</a></h4>
|
|
<p>In your application's deployment config, reference the credential Secret that the registrar creates:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-72-1" name="__codelineno-72-1" href="#__codelineno-72-1"></a><span class="nt">env</span><span class="p">:</span>
|
|
<a id="__codelineno-72-2" name="__codelineno-72-2" href="#__codelineno-72-2"></a><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">OIDC_CLIENT_ID</span>
|
|
<a id="__codelineno-72-3" name="__codelineno-72-3" href="#__codelineno-72-3"></a><span class="w"> </span><span class="nt">valueFrom</span><span class="p">:</span>
|
|
<a id="__codelineno-72-4" name="__codelineno-72-4" href="#__codelineno-72-4"></a><span class="w"> </span><span class="nt">secretKeyRef</span><span class="p">:</span>
|
|
<a id="__codelineno-72-5" name="__codelineno-72-5" href="#__codelineno-72-5"></a><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">myapp-oidc-credentials</span>
|
|
<a id="__codelineno-72-6" name="__codelineno-72-6" href="#__codelineno-72-6"></a><span class="w"> </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">client-id</span>
|
|
<a id="__codelineno-72-7" name="__codelineno-72-7" href="#__codelineno-72-7"></a><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">OIDC_CLIENT_SECRET</span>
|
|
<a id="__codelineno-72-8" name="__codelineno-72-8" href="#__codelineno-72-8"></a><span class="w"> </span><span class="nt">valueFrom</span><span class="p">:</span>
|
|
<a id="__codelineno-72-9" name="__codelineno-72-9" href="#__codelineno-72-9"></a><span class="w"> </span><span class="nt">secretKeyRef</span><span class="p">:</span>
|
|
<a id="__codelineno-72-10" name="__codelineno-72-10" href="#__codelineno-72-10"></a><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">myapp-oidc-credentials</span>
|
|
<a id="__codelineno-72-11" name="__codelineno-72-11" href="#__codelineno-72-11"></a><span class="w"> </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">client-secret</span>
|
|
</code></pre></div>
|
|
<h4 id="step-3-deploy-and-wait">Step 3: Deploy and Wait<a class="headerlink" href="#step-3-deploy-and-wait" title="Permanent link">¶</a></h4>
|
|
<p>Commit and push your changes. The credential Secret will appear within 2 minutes:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-73-1" name="__codelineno-73-1" href="#__codelineno-73-1"></a><span class="c1"># Watch for the credential Secret to be created</span>
|
|
<a id="__codelineno-73-2" name="__codelineno-73-2" href="#__codelineno-73-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secret<span class="w"> </span>myapp-oidc-credentials<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span>-w
|
|
<a id="__codelineno-73-3" name="__codelineno-73-3" href="#__codelineno-73-3"></a>
|
|
<a id="__codelineno-73-4" name="__codelineno-73-4" href="#__codelineno-73-4"></a><span class="c1"># Check registrar logs</span>
|
|
<a id="__codelineno-73-5" name="__codelineno-73-5" href="#__codelineno-73-5"></a>kubectl<span class="w"> </span>logs<span class="w"> </span>-n<span class="w"> </span>keycloak<span class="w"> </span>job/<span class="k">$(</span>kubectl<span class="w"> </span>get<span class="w"> </span><span class="nb">jobs</span><span class="w"> </span>-n<span class="w"> </span>keycloak<span class="w"> </span>--sort-by<span class="o">=</span>.metadata.creationTimestamp<span class="w"> </span>-o<span class="w"> </span><span class="nv">jsonpath</span><span class="o">=</span><span class="s1">'{.items[-1].metadata.name}'</span><span class="k">)</span>
|
|
<a id="__codelineno-73-6" name="__codelineno-73-6" href="#__codelineno-73-6"></a>
|
|
<a id="__codelineno-73-7" name="__codelineno-73-7" href="#__codelineno-73-7"></a><span class="c1"># Check sync status on the config Secret</span>
|
|
<a id="__codelineno-73-8" name="__codelineno-73-8" href="#__codelineno-73-8"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secret<span class="w"> </span>keycloak-client-myapp<span class="w"> </span>-n<span class="w"> </span>keycloak<span class="w"> </span>-o<span class="w"> </span><span class="nv">jsonpath</span><span class="o">=</span><span class="s1">'{.metadata.annotations}'</span>
|
|
</code></pre></div>
|
|
<h4 id="change-detection">Change Detection<a class="headerlink" href="#change-detection" title="Permanent link">¶</a></h4>
|
|
<p>The registrar computes a SHA-256 hash of <code>client.json</code> and stores it as an annotation. On subsequent runs, it skips processing if:
|
|
- The hash hasn't changed, AND
|
|
- The credential Secret already exists in the target namespace</p>
|
|
<p>To force a re-sync, update any field in <code>client.json</code> (e.g., add a trailing space to <code>name</code>).</p>
|
|
<h3 id="legacy-method-realm-json">Legacy Method: Realm JSON<a class="headerlink" href="#legacy-method-realm-json" title="Permanent link">¶</a></h3>
|
|
<p>Existing clients (like Gitea) are defined directly in <code>forte-realm.json</code> inside <code>keycloak-values.yaml</code>. The registrar syncs their secrets via client attributes.</p>
|
|
<h4 id="step-1-add-client-to-realm-config">Step 1: Add Client to Realm Config<a class="headerlink" href="#step-1-add-client-to-realm-config" title="Permanent link">¶</a></h4>
|
|
<p>In <code>infra/values/base/keycloak-values.yaml</code>, add a new entry to the <code>clients</code> array in <code>forte-realm.json</code>:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-74-1" name="__codelineno-74-1" href="#__codelineno-74-1"></a><span class="p">{</span>
|
|
<a id="__codelineno-74-2" name="__codelineno-74-2" href="#__codelineno-74-2"></a><span class="w"> </span><span class="nt">"clientId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"myapp"</span><span class="p">,</span>
|
|
<a id="__codelineno-74-3" name="__codelineno-74-3" href="#__codelineno-74-3"></a><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"My Application"</span><span class="p">,</span>
|
|
<a id="__codelineno-74-4" name="__codelineno-74-4" href="#__codelineno-74-4"></a><span class="w"> </span><span class="nt">"enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
<a id="__codelineno-74-5" name="__codelineno-74-5" href="#__codelineno-74-5"></a><span class="w"> </span><span class="nt">"protocol"</span><span class="p">:</span><span class="w"> </span><span class="s2">"openid-connect"</span><span class="p">,</span>
|
|
<a id="__codelineno-74-6" name="__codelineno-74-6" href="#__codelineno-74-6"></a><span class="w"> </span><span class="nt">"clientAuthenticatorType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"client-secret"</span><span class="p">,</span>
|
|
<a id="__codelineno-74-7" name="__codelineno-74-7" href="#__codelineno-74-7"></a><span class="w"> </span><span class="nt">"standardFlowEnabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
<a id="__codelineno-74-8" name="__codelineno-74-8" href="#__codelineno-74-8"></a><span class="w"> </span><span class="nt">"directAccessGrantsEnabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
|
|
<a id="__codelineno-74-9" name="__codelineno-74-9" href="#__codelineno-74-9"></a><span class="w"> </span><span class="nt">"publicClient"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
|
|
<a id="__codelineno-74-10" name="__codelineno-74-10" href="#__codelineno-74-10"></a><span class="w"> </span><span class="nt">"redirectUris"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"https://myapp.forteapps.net/*"</span><span class="p">],</span>
|
|
<a id="__codelineno-74-11" name="__codelineno-74-11" href="#__codelineno-74-11"></a><span class="w"> </span><span class="nt">"webOrigins"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"https://myapp.forteapps.net"</span><span class="p">],</span>
|
|
<a id="__codelineno-74-12" name="__codelineno-74-12" href="#__codelineno-74-12"></a><span class="w"> </span><span class="nt">"defaultClientScopes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"openid"</span><span class="p">,</span><span class="w"> </span><span class="s2">"email"</span><span class="p">,</span><span class="w"> </span><span class="s2">"profile"</span><span class="p">],</span>
|
|
<a id="__codelineno-74-13" name="__codelineno-74-13" href="#__codelineno-74-13"></a><span class="w"> </span><span class="nt">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
|
<a id="__codelineno-74-14" name="__codelineno-74-14" href="#__codelineno-74-14"></a><span class="w"> </span><span class="nt">"k8s.secret.sync"</span><span class="p">:</span><span class="w"> </span><span class="s2">"true"</span><span class="p">,</span>
|
|
<a id="__codelineno-74-15" name="__codelineno-74-15" href="#__codelineno-74-15"></a><span class="w"> </span><span class="nt">"k8s.secret.namespace"</span><span class="p">:</span><span class="w"> </span><span class="s2">"myapp"</span><span class="p">,</span>
|
|
<a id="__codelineno-74-16" name="__codelineno-74-16" href="#__codelineno-74-16"></a><span class="w"> </span><span class="nt">"k8s.secret.name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"myapp-oidc-credentials"</span><span class="p">,</span>
|
|
<a id="__codelineno-74-17" name="__codelineno-74-17" href="#__codelineno-74-17"></a><span class="w"> </span><span class="nt">"k8s.secret.client-id-key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"key"</span><span class="p">,</span>
|
|
<a id="__codelineno-74-18" name="__codelineno-74-18" href="#__codelineno-74-18"></a><span class="w"> </span><span class="nt">"k8s.secret.client-secret-key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"secret"</span>
|
|
<a id="__codelineno-74-19" name="__codelineno-74-19" href="#__codelineno-74-19"></a><span class="w"> </span><span class="p">}</span>
|
|
<a id="__codelineno-74-20" name="__codelineno-74-20" href="#__codelineno-74-20"></a><span class="p">}</span>
|
|
</code></pre></div>
|
|
<p><strong>Important</strong>:
|
|
- Do <strong>NOT</strong> include a <code>"secret"</code> field — Keycloak generates one automatically
|
|
- The <code>attributes</code> block tells the registrar where to create the K8s Secret
|
|
- Set <code>client-id-key</code> / <code>client-secret-key</code> to match what the consuming app expects (defaults: <code>client-id</code> / <code>client-secret</code>)</p>
|
|
<h4 id="step-2-reference-the-secret-in-your-application">Step 2: Reference the Secret in Your Application<a class="headerlink" href="#step-2-reference-the-secret-in-your-application" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-75-1" name="__codelineno-75-1" href="#__codelineno-75-1"></a><span class="nt">existingSecret</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">myapp-oidc-credentials</span>
|
|
</code></pre></div>
|
|
<h4 id="step-3-commit-and-push">Step 3: Commit and Push<a class="headerlink" href="#step-3-commit-and-push" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-76-1" name="__codelineno-76-1" href="#__codelineno-76-1"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/launchpad
|
|
<a id="__codelineno-76-2" name="__codelineno-76-2" href="#__codelineno-76-2"></a>git<span class="w"> </span>add<span class="w"> </span>infra/values/base/keycloak-values.yaml
|
|
<a id="__codelineno-76-3" name="__codelineno-76-3" href="#__codelineno-76-3"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Add myapp Keycloak client with auto-sync"</span>
|
|
<a id="__codelineno-76-4" name="__codelineno-76-4" href="#__codelineno-76-4"></a>git<span class="w"> </span>push
|
|
</code></pre></div>
|
|
<p>ArgoCD will sync the Keycloak config, and the registrar CronJob will pick up the new client within 2 minutes.</p>
|
|
<h4 id="legacy-sync-attribute-reference">Legacy Sync Attribute Reference<a class="headerlink" href="#legacy-sync-attribute-reference" title="Permanent link">¶</a></h4>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Attribute</th>
|
|
<th>Required</th>
|
|
<th>Default</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>k8s.secret.sync</code></td>
|
|
<td>Yes</td>
|
|
<td>—</td>
|
|
<td>Set to <code>"true"</code> to enable syncing</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>k8s.secret.namespace</code></td>
|
|
<td>Yes</td>
|
|
<td>—</td>
|
|
<td>Target K8s namespace for the secret</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>k8s.secret.name</code></td>
|
|
<td>Yes</td>
|
|
<td>—</td>
|
|
<td>Name of the K8s Secret to create</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>k8s.secret.client-id-key</code></td>
|
|
<td>No</td>
|
|
<td><code>client-id</code></td>
|
|
<td>Field name for the client ID in the K8s Secret</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>k8s.secret.client-secret-key</code></td>
|
|
<td>No</td>
|
|
<td><code>client-secret</code></td>
|
|
<td>Field name for the client secret in the K8s Secret</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="retrieving-secrets-for-external-deployments">Retrieving Secrets for External Deployments<a class="headerlink" href="#retrieving-secrets-for-external-deployments" title="Permanent link">¶</a></h3>
|
|
<p>The registrar always writes a <strong>central copy</strong> of every synced secret to the <code>secrets</code> namespace, in addition to the target namespace. This allows operators to retrieve client credentials for applications deployed outside this cluster:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-77-1" name="__codelineno-77-1" href="#__codelineno-77-1"></a><span class="c1"># View the central copy</span>
|
|
<a id="__codelineno-77-2" name="__codelineno-77-2" href="#__codelineno-77-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secret<span class="w"> </span>gitea-oidc-credentials<span class="w"> </span>-n<span class="w"> </span>secrets<span class="w"> </span>-o<span class="w"> </span>yaml
|
|
<a id="__codelineno-77-3" name="__codelineno-77-3" href="#__codelineno-77-3"></a>
|
|
<a id="__codelineno-77-4" name="__codelineno-77-4" href="#__codelineno-77-4"></a><span class="c1"># Extract the client secret for use elsewhere</span>
|
|
<a id="__codelineno-77-5" name="__codelineno-77-5" href="#__codelineno-77-5"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secret<span class="w"> </span>myapp-oidc-credentials<span class="w"> </span>-n<span class="w"> </span>secrets<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-77-6" name="__codelineno-77-6" href="#__codelineno-77-6"></a><span class="w"> </span>-o<span class="w"> </span><span class="nv">jsonpath</span><span class="o">=</span><span class="s1">'{.data.client-secret}'</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>base64<span class="w"> </span>-d
|
|
</code></pre></div>
|
|
<h3 id="registrar-behavior-notes">Registrar Behavior Notes<a class="headerlink" href="#registrar-behavior-notes" title="Permanent link">¶</a></h3>
|
|
<ul>
|
|
<li>The registrar runs as a CronJob every 2 minutes (<code>concurrencyPolicy: Forbid</code>)</li>
|
|
<li>If the target namespace doesn't exist, the target write is skipped with a warning (the central copy still happens)</li>
|
|
<li>A central copy is <strong>always</strong> written to the <code>secrets</code> namespace for every synced client</li>
|
|
<li>The registrar uses the <code>keycloak-credentials</code> secret for admin authentication</li>
|
|
<li>Created secrets have the label <code>app.kubernetes.io/managed-by: keycloak-client-registrar</code></li>
|
|
</ul>
|
|
<hr />
|
|
<h2 id="troubleshooting">Troubleshooting<a class="headerlink" href="#troubleshooting" title="Permanent link">¶</a></h2>
|
|
<h3 id="application-not-deploying">Application Not Deploying<a class="headerlink" href="#application-not-deploying" title="Permanent link">¶</a></h3>
|
|
<h4 id="problem-application-stuck-in-syncing-state">Problem: Application stuck in "Syncing" state<a class="headerlink" href="#problem-application-stuck-in-syncing-state" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check ArgoCD status:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-78-1" name="__codelineno-78-1" href="#__codelineno-78-1"></a>kubectl<span class="w"> </span>get<span class="w"> </span>application<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>argocd<span class="w"> </span>-o<span class="w"> </span>yaml
|
|
</code></pre></div></p>
|
|
<p>Look for errors in <code>status.conditions</code>.</p>
|
|
<p><strong>Common causes:</strong>
|
|
- ❌ Image doesn't exist or is not accessible
|
|
- ❌ Invalid YAML syntax
|
|
- ❌ Resource quota exceeded
|
|
- ❌ Namespace conflicts
|
|
- ❌ Invalid Helm values</p>
|
|
<p><strong>Solutions:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-79-1" name="__codelineno-79-1" href="#__codelineno-79-1"></a><span class="c1"># Check image exists</span>
|
|
<a id="__codelineno-79-2" name="__codelineno-79-2" href="#__codelineno-79-2"></a>docker<span class="w"> </span>pull<span class="w"> </span>ghcr.io/fortedigital/myapp:v1.0.0
|
|
<a id="__codelineno-79-3" name="__codelineno-79-3" href="#__codelineno-79-3"></a>
|
|
<a id="__codelineno-79-4" name="__codelineno-79-4" href="#__codelineno-79-4"></a><span class="c1"># Validate YAML syntax</span>
|
|
<a id="__codelineno-79-5" name="__codelineno-79-5" href="#__codelineno-79-5"></a>kubectl<span class="w"> </span>apply<span class="w"> </span>--dry-run<span class="o">=</span>client<span class="w"> </span>-f<span class="w"> </span>apps/myapp.yaml
|
|
<a id="__codelineno-79-6" name="__codelineno-79-6" href="#__codelineno-79-6"></a>
|
|
<a id="__codelineno-79-7" name="__codelineno-79-7" href="#__codelineno-79-7"></a><span class="c1"># Check ArgoCD logs</span>
|
|
<a id="__codelineno-79-8" name="__codelineno-79-8" href="#__codelineno-79-8"></a>kubectl<span class="w"> </span>logs<span class="w"> </span>-n<span class="w"> </span>argocd<span class="w"> </span>deployment/argocd-application-controller<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>myapp
|
|
</code></pre></div></p>
|
|
<h4 id="problem-pods-crashing-crashloopbackoff">Problem: Pods crashing (CrashLoopBackOff)<a class="headerlink" href="#problem-pods-crashing-crashloopbackoff" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check pod logs:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-80-1" name="__codelineno-80-1" href="#__codelineno-80-1"></a>kubectl<span class="w"> </span>get<span class="w"> </span>pods<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-80-2" name="__codelineno-80-2" href="#__codelineno-80-2"></a>kubectl<span class="w"> </span>logs<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span><pod-name>
|
|
<a id="__codelineno-80-3" name="__codelineno-80-3" href="#__codelineno-80-3"></a>kubectl<span class="w"> </span>describe<span class="w"> </span>pod<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span><pod-name>
|
|
</code></pre></div></p>
|
|
<p><strong>Common causes:</strong>
|
|
- ❌ Application error (check logs)
|
|
- ❌ Missing environment variables
|
|
- ❌ Incorrect port configuration
|
|
- ❌ Missing secrets
|
|
- ❌ Insufficient resources</p>
|
|
<p><strong>Solutions:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-81-1" name="__codelineno-81-1" href="#__codelineno-81-1"></a><span class="c1"># Check environment variables</span>
|
|
<a id="__codelineno-81-2" name="__codelineno-81-2" href="#__codelineno-81-2"></a>kubectl<span class="w"> </span><span class="nb">exec</span><span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span><pod-name><span class="w"> </span>--<span class="w"> </span>env
|
|
<a id="__codelineno-81-3" name="__codelineno-81-3" href="#__codelineno-81-3"></a>
|
|
<a id="__codelineno-81-4" name="__codelineno-81-4" href="#__codelineno-81-4"></a><span class="c1"># Check if secrets exist</span>
|
|
<a id="__codelineno-81-5" name="__codelineno-81-5" href="#__codelineno-81-5"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secrets<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-81-6" name="__codelineno-81-6" href="#__codelineno-81-6"></a>
|
|
<a id="__codelineno-81-7" name="__codelineno-81-7" href="#__codelineno-81-7"></a><span class="c1"># Increase resources in helm-values</span>
|
|
<a id="__codelineno-81-8" name="__codelineno-81-8" href="#__codelineno-81-8"></a>vim<span class="w"> </span>~/dev/k8s/helm-prod-values/myapp/values.yaml
|
|
</code></pre></div></p>
|
|
<h4 id="problem-application-not-accessible-via-domain">Problem: Application not accessible via domain<a class="headerlink" href="#problem-application-not-accessible-via-domain" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check ingress:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-82-1" name="__codelineno-82-1" href="#__codelineno-82-1"></a>kubectl<span class="w"> </span>get<span class="w"> </span>ingressroute<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-82-2" name="__codelineno-82-2" href="#__codelineno-82-2"></a>kubectl<span class="w"> </span>describe<span class="w"> </span>ingressroute<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
</code></pre></div></p>
|
|
<p><strong>Common causes:</strong>
|
|
- ❌ DNS not configured
|
|
- ❌ TLS certificate not issued
|
|
- ❌ Incorrect domain in values.yaml
|
|
- ❌ Traefik not routing correctly</p>
|
|
<p><strong>Solutions:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-83-1" name="__codelineno-83-1" href="#__codelineno-83-1"></a><span class="c1"># Check certificate</span>
|
|
<a id="__codelineno-83-2" name="__codelineno-83-2" href="#__codelineno-83-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>certificate<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-83-3" name="__codelineno-83-3" href="#__codelineno-83-3"></a>
|
|
<a id="__codelineno-83-4" name="__codelineno-83-4" href="#__codelineno-83-4"></a><span class="c1"># Check cert-manager logs</span>
|
|
<a id="__codelineno-83-5" name="__codelineno-83-5" href="#__codelineno-83-5"></a>kubectl<span class="w"> </span>logs<span class="w"> </span>-n<span class="w"> </span>cert-manager<span class="w"> </span>deployment/cert-manager
|
|
<a id="__codelineno-83-6" name="__codelineno-83-6" href="#__codelineno-83-6"></a>
|
|
<a id="__codelineno-83-7" name="__codelineno-83-7" href="#__codelineno-83-7"></a><span class="c1"># Verify domain configuration</span>
|
|
<a id="__codelineno-83-8" name="__codelineno-83-8" href="#__codelineno-83-8"></a>cat<span class="w"> </span>~/dev/k8s/helm-prod-values/myapp/values.yaml<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>host
|
|
<a id="__codelineno-83-9" name="__codelineno-83-9" href="#__codelineno-83-9"></a>
|
|
<a id="__codelineno-83-10" name="__codelineno-83-10" href="#__codelineno-83-10"></a><span class="c1"># Test with port-forward</span>
|
|
<a id="__codelineno-83-11" name="__codelineno-83-11" href="#__codelineno-83-11"></a>kubectl<span class="w"> </span>port-forward<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span>service/myapp<span class="w"> </span><span class="m">8080</span>:3000
|
|
<a id="__codelineno-83-12" name="__codelineno-83-12" href="#__codelineno-83-12"></a>curl<span class="w"> </span>http://localhost:8080
|
|
</code></pre></div></p>
|
|
<h3 id="secret-issues">Secret Issues<a class="headerlink" href="#secret-issues" title="Permanent link">¶</a></h3>
|
|
<h4 id="problem-secret-not-found">Problem: Secret not found<a class="headerlink" href="#problem-secret-not-found" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check if SealedSecret exists:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-84-1" name="__codelineno-84-1" href="#__codelineno-84-1"></a>kubectl<span class="w"> </span>get<span class="w"> </span>sealedsecret<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-84-2" name="__codelineno-84-2" href="#__codelineno-84-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secret<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
</code></pre></div></p>
|
|
<p><strong>Solutions:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-85-1" name="__codelineno-85-1" href="#__codelineno-85-1"></a><span class="c1"># Check if secret is in Git</span>
|
|
<a id="__codelineno-85-2" name="__codelineno-85-2" href="#__codelineno-85-2"></a>ls<span class="w"> </span>-l<span class="w"> </span>secrets/myapp-credentials-sealed.yaml
|
|
<a id="__codelineno-85-3" name="__codelineno-85-3" href="#__codelineno-85-3"></a>
|
|
<a id="__codelineno-85-4" name="__codelineno-85-4" href="#__codelineno-85-4"></a><span class="c1"># Re-apply sealed secret</span>
|
|
<a id="__codelineno-85-5" name="__codelineno-85-5" href="#__codelineno-85-5"></a>kubectl<span class="w"> </span>apply<span class="w"> </span>-f<span class="w"> </span>secrets/myapp-credentials-sealed.yaml
|
|
<a id="__codelineno-85-6" name="__codelineno-85-6" href="#__codelineno-85-6"></a>
|
|
<a id="__codelineno-85-7" name="__codelineno-85-7" href="#__codelineno-85-7"></a><span class="c1"># Check sealed-secrets-controller logs</span>
|
|
<a id="__codelineno-85-8" name="__codelineno-85-8" href="#__codelineno-85-8"></a>kubectl<span class="w"> </span>logs<span class="w"> </span>-n<span class="w"> </span>kube-system<span class="w"> </span>deployment/sealed-secrets-controller
|
|
</code></pre></div></p>
|
|
<h4 id="problem-secret-exists-but-pods-cant-access-it">Problem: Secret exists but pods can't access it<a class="headerlink" href="#problem-secret-exists-but-pods-cant-access-it" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check pod events:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-86-1" name="__codelineno-86-1" href="#__codelineno-86-1"></a>kubectl<span class="w"> </span>describe<span class="w"> </span>pod<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span><pod-name>
|
|
</code></pre></div></p>
|
|
<p>Look for: <code>Error: secret "myapp-credentials" not found</code></p>
|
|
<p><strong>Solutions:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-87-1" name="__codelineno-87-1" href="#__codelineno-87-1"></a><span class="c1"># Verify secret name in values.yaml matches actual secret</span>
|
|
<a id="__codelineno-87-2" name="__codelineno-87-2" href="#__codelineno-87-2"></a>cat<span class="w"> </span>~/dev/k8s/helm-prod-values/myapp/values.yaml<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>envSecretName
|
|
<a id="__codelineno-87-3" name="__codelineno-87-3" href="#__codelineno-87-3"></a>kubectl<span class="w"> </span>get<span class="w"> </span>secrets<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-87-4" name="__codelineno-87-4" href="#__codelineno-87-4"></a>
|
|
<a id="__codelineno-87-5" name="__codelineno-87-5" href="#__codelineno-87-5"></a><span class="c1"># Restart pods</span>
|
|
<a id="__codelineno-87-6" name="__codelineno-87-6" href="#__codelineno-87-6"></a>kubectl<span class="w"> </span>rollout<span class="w"> </span>restart<span class="w"> </span>deployment<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
</code></pre></div></p>
|
|
<h3 id="sync-failures">Sync Failures<a class="headerlink" href="#sync-failures" title="Permanent link">¶</a></h3>
|
|
<h4 id="problem-argocd-shows-out-of-sync">Problem: ArgoCD shows "Out of Sync"<a class="headerlink" href="#problem-argocd-shows-out-of-sync" title="Permanent link">¶</a></h4>
|
|
<p><strong>Manual sync:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-88-1" name="__codelineno-88-1" href="#__codelineno-88-1"></a><span class="c1"># Using kubectl</span>
|
|
<a id="__codelineno-88-2" name="__codelineno-88-2" href="#__codelineno-88-2"></a>kubectl<span class="w"> </span>patch<span class="w"> </span>application<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>argocd<span class="w"> </span>--type<span class="w"> </span>merge<span class="w"> </span>-p<span class="w"> </span><span class="s1">'{"operation":{"initiatedBy":{"username":"admin"},"sync":{"syncStrategy":{"hook":{}}}}}'</span>
|
|
<a id="__codelineno-88-3" name="__codelineno-88-3" href="#__codelineno-88-3"></a>
|
|
<a id="__codelineno-88-4" name="__codelineno-88-4" href="#__codelineno-88-4"></a><span class="c1"># Or via ArgoCD UI</span>
|
|
<a id="__codelineno-88-5" name="__codelineno-88-5" href="#__codelineno-88-5"></a><span class="c1"># Click "Sync" button in UI</span>
|
|
</code></pre></div></p>
|
|
<p><strong>Check what's different:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-89-1" name="__codelineno-89-1" href="#__codelineno-89-1"></a>kubectl<span class="w"> </span>get<span class="w"> </span>application<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>argocd<span class="w"> </span>-o<span class="w"> </span>yaml
|
|
</code></pre></div></p>
|
|
<p>Look at <code>status.sync.comparedTo</code> vs desired state.</p>
|
|
<h4 id="problem-sync-succeeds-but-application-is-degraded">Problem: Sync succeeds but application is "Degraded"<a class="headerlink" href="#problem-sync-succeeds-but-application-is-degraded" title="Permanent link">¶</a></h4>
|
|
<p><strong>Check resource health:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-90-1" name="__codelineno-90-1" href="#__codelineno-90-1"></a>kubectl<span class="w"> </span>get<span class="w"> </span>application<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>argocd<span class="w"> </span>-o<span class="w"> </span><span class="nv">jsonpath</span><span class="o">=</span><span class="s1">'{.status.resources[*].health}'</span>
|
|
</code></pre></div></p>
|
|
<p><strong>Common causes:</strong>
|
|
- ❌ Pods not ready
|
|
- ❌ Deployments not at desired replica count
|
|
- ❌ Jobs failed</p>
|
|
<p><strong>Solutions:</strong>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-91-1" name="__codelineno-91-1" href="#__codelineno-91-1"></a><span class="c1"># Check all resources in namespace</span>
|
|
<a id="__codelineno-91-2" name="__codelineno-91-2" href="#__codelineno-91-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>all<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-91-3" name="__codelineno-91-3" href="#__codelineno-91-3"></a>
|
|
<a id="__codelineno-91-4" name="__codelineno-91-4" href="#__codelineno-91-4"></a><span class="c1"># Check pod events</span>
|
|
<a id="__codelineno-91-5" name="__codelineno-91-5" href="#__codelineno-91-5"></a>kubectl<span class="w"> </span>get<span class="w"> </span>events<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span>--sort-by<span class="o">=</span><span class="s1">'.lastTimestamp'</span>
|
|
</code></pre></div></p>
|
|
<h3 id="getting-help">Getting Help<a class="headerlink" href="#getting-help" title="Permanent link">¶</a></h3>
|
|
<p>If you're stuck:</p>
|
|
<ol>
|
|
<li><strong>Check Slack notifications</strong> - Error details are often in sync failure messages</li>
|
|
<li><strong>Check ArgoCD UI</strong> - Visual representation of what's wrong</li>
|
|
<li><strong>Ask platform team</strong> - They have full cluster access and can debug further</li>
|
|
<li><strong>Check documentation</strong> - <a href="../OPERATIONS-RUNBOOK/">Operations Runbook</a> has more troubleshooting</li>
|
|
</ol>
|
|
<hr />
|
|
<h2 id="documentation">Documentation<a class="headerlink" href="#documentation" title="Permanent link">¶</a></h2>
|
|
<p>This repository's documentation is built with <a href="https://www.mkdocs.org/">MkDocs</a> using the <a href="https://squidfund.github.io/mkdocs-material/">Material</a> theme and published automatically to Gitea Pages.</p>
|
|
<h3 id="viewing-the-docs">Viewing the Docs<a class="headerlink" href="#viewing-the-docs" title="Permanent link">¶</a></h3>
|
|
<p>The live documentation site is available at:</p>
|
|
<p><strong>https://git.forteapps.net/Forte/launchpad/pages/</strong></p>
|
|
<h3 id="editing-documentation">Editing Documentation<a class="headerlink" href="#editing-documentation" title="Permanent link">¶</a></h3>
|
|
<p>All documentation source files live in the <code>docs/</code> directory as Markdown. To make changes:</p>
|
|
<ol>
|
|
<li>Edit the relevant <code>.md</code> file in <code>docs/</code></li>
|
|
<li>Commit and push to <code>main</code></li>
|
|
<li>The Gitea Actions workflow automatically rebuilds and deploys the site</li>
|
|
</ol>
|
|
<h3 id="local-preview">Local Preview<a class="headerlink" href="#local-preview" title="Permanent link">¶</a></h3>
|
|
<p>To preview documentation changes locally before pushing:</p>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-92-1" name="__codelineno-92-1" href="#__codelineno-92-1"></a><span class="c1"># Install dependencies (one-time)</span>
|
|
<a id="__codelineno-92-2" name="__codelineno-92-2" href="#__codelineno-92-2"></a>pip<span class="w"> </span>install<span class="w"> </span>mkdocs<span class="w"> </span>mkdocs-material
|
|
<a id="__codelineno-92-3" name="__codelineno-92-3" href="#__codelineno-92-3"></a>
|
|
<a id="__codelineno-92-4" name="__codelineno-92-4" href="#__codelineno-92-4"></a><span class="c1"># Start the local dev server</span>
|
|
<a id="__codelineno-92-5" name="__codelineno-92-5" href="#__codelineno-92-5"></a>mkdocs<span class="w"> </span>serve
|
|
</code></pre></div>
|
|
<p>Then open <code>http://127.0.0.1:8000</code> in your browser. The server live-reloads on file changes.</p>
|
|
<h3 id="how-it-works_2">How It Works<a class="headerlink" href="#how-it-works_2" title="Permanent link">¶</a></h3>
|
|
<ul>
|
|
<li><strong>Workflow</strong>: <code>.gitea/workflows/docs.yaml</code> triggers on pushes to <code>main</code> that change <code>docs/**</code>, <code>mkdocs.yml</code>, <code>Dockerfile.docs</code>, or <code>nginx.conf</code></li>
|
|
<li><strong>Build</strong>: Installs MkDocs + Material theme, runs <code>mkdocs build</code></li>
|
|
<li><strong>Deploy</strong>: Force-pushes the built <code>site/</code> directory to the <code>gitea-pages</code> branch</li>
|
|
<li><strong>Serve</strong>: Gitea Pages serves the static site from the <code>gitea-pages</code> branch</li>
|
|
</ul>
|
|
<hr />
|
|
<h2 id="best-practices">Best Practices<a class="headerlink" href="#best-practices" title="Permanent link">¶</a></h2>
|
|
<h3 id="development-workflow">Development Workflow<a class="headerlink" href="#development-workflow" title="Permanent link">¶</a></h3>
|
|
<p>✅ <strong>DO</strong>:
|
|
- Develop and test locally with Docker Compose
|
|
- Use semantic versioning for releases
|
|
- Write descriptive commit messages
|
|
- Test changes in a separate namespace first (if possible)
|
|
- Monitor Slack for deployment notifications
|
|
- Document environment variables and configuration</p>
|
|
<p>❌ <strong>DON'T</strong>:
|
|
- Push directly to production without testing
|
|
- Use <code>latest</code> tag for Docker images
|
|
- Bypass CI/CD for "quick fixes"
|
|
- Hard-code configuration values
|
|
- Ignore deployment failures</p>
|
|
<h3 id="configuration-management">Configuration Management<a class="headerlink" href="#configuration-management" title="Permanent link">¶</a></h3>
|
|
<p>✅ <strong>DO</strong>:
|
|
- Keep configuration in <code>helm-values</code> repository
|
|
- Use environment variables for config
|
|
- Document what each value does
|
|
- Use reasonable resource limits
|
|
- Enable ingress and TLS for public services</p>
|
|
<p>❌ <strong>DON'T</strong>:
|
|
- Hard-code config in application code
|
|
- Over-allocate resources (wastes money)
|
|
- Under-allocate resources (causes crashes)
|
|
- Use HTTP for production services</p>
|
|
<h3 id="secret-management">Secret Management<a class="headerlink" href="#secret-management" title="Permanent link">¶</a></h3>
|
|
<p>✅ <strong>DO</strong>:
|
|
- Use kubeseal for all secrets
|
|
- Store plain secrets in password manager
|
|
- Rotate secrets regularly
|
|
- Use different secrets per environment
|
|
- Document what each secret contains</p>
|
|
<p>❌ <strong>DON'T</strong>:
|
|
- Commit plain secrets
|
|
- Share secrets in Slack/email
|
|
- Reuse secrets across apps
|
|
- Log secrets in application code</p>
|
|
<h3 id="git-workflow">Git Workflow<a class="headerlink" href="#git-workflow" title="Permanent link">¶</a></h3>
|
|
<p>✅ <strong>DO</strong>:
|
|
- Use feature branches for changes
|
|
- Write clear commit messages
|
|
- Use pull requests for review
|
|
- Keep commits atomic and focused
|
|
- Tag releases in application repos</p>
|
|
<p>❌ <strong>DON'T</strong>:
|
|
- Push directly to <code>main</code> without review (for config repos)
|
|
- Make multiple unrelated changes in one commit
|
|
- Use vague commit messages ("fix", "update")
|
|
- Force-push to main branches</p>
|
|
<hr />
|
|
<h2 id="quick-reference">Quick Reference<a class="headerlink" href="#quick-reference" title="Permanent link">¶</a></h2>
|
|
<h3 id="common-commands">Common Commands<a class="headerlink" href="#common-commands" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-93-1" name="__codelineno-93-1" href="#__codelineno-93-1"></a><span class="c1"># Check application status</span>
|
|
<a id="__codelineno-93-2" name="__codelineno-93-2" href="#__codelineno-93-2"></a>kubectl<span class="w"> </span>get<span class="w"> </span>application<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>argocd
|
|
<a id="__codelineno-93-3" name="__codelineno-93-3" href="#__codelineno-93-3"></a>
|
|
<a id="__codelineno-93-4" name="__codelineno-93-4" href="#__codelineno-93-4"></a><span class="c1"># View application details</span>
|
|
<a id="__codelineno-93-5" name="__codelineno-93-5" href="#__codelineno-93-5"></a>kubectl<span class="w"> </span>describe<span class="w"> </span>application<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>argocd
|
|
<a id="__codelineno-93-6" name="__codelineno-93-6" href="#__codelineno-93-6"></a>
|
|
<a id="__codelineno-93-7" name="__codelineno-93-7" href="#__codelineno-93-7"></a><span class="c1"># Check pods</span>
|
|
<a id="__codelineno-93-8" name="__codelineno-93-8" href="#__codelineno-93-8"></a>kubectl<span class="w"> </span>get<span class="w"> </span>pods<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-93-9" name="__codelineno-93-9" href="#__codelineno-93-9"></a>
|
|
<a id="__codelineno-93-10" name="__codelineno-93-10" href="#__codelineno-93-10"></a><span class="c1"># View pod logs</span>
|
|
<a id="__codelineno-93-11" name="__codelineno-93-11" href="#__codelineno-93-11"></a>kubectl<span class="w"> </span>logs<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span><pod-name>
|
|
<a id="__codelineno-93-12" name="__codelineno-93-12" href="#__codelineno-93-12"></a>
|
|
<a id="__codelineno-93-13" name="__codelineno-93-13" href="#__codelineno-93-13"></a><span class="c1"># Restart deployment</span>
|
|
<a id="__codelineno-93-14" name="__codelineno-93-14" href="#__codelineno-93-14"></a>kubectl<span class="w"> </span>rollout<span class="w"> </span>restart<span class="w"> </span>deployment<span class="w"> </span>myapp<span class="w"> </span>-n<span class="w"> </span>myapp
|
|
<a id="__codelineno-93-15" name="__codelineno-93-15" href="#__codelineno-93-15"></a>
|
|
<a id="__codelineno-93-16" name="__codelineno-93-16" href="#__codelineno-93-16"></a><span class="c1"># Port-forward to service</span>
|
|
<a id="__codelineno-93-17" name="__codelineno-93-17" href="#__codelineno-93-17"></a>kubectl<span class="w"> </span>port-forward<span class="w"> </span>-n<span class="w"> </span>myapp<span class="w"> </span>service/myapp<span class="w"> </span><span class="m">8080</span>:3000
|
|
<a id="__codelineno-93-18" name="__codelineno-93-18" href="#__codelineno-93-18"></a>
|
|
<a id="__codelineno-93-19" name="__codelineno-93-19" href="#__codelineno-93-19"></a><span class="c1"># Create secret</span>
|
|
<a id="__codelineno-93-20" name="__codelineno-93-20" href="#__codelineno-93-20"></a>kubectl<span class="w"> </span>create<span class="w"> </span>secret<span class="w"> </span>generic<span class="w"> </span>myapp-credentials<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-93-21" name="__codelineno-93-21" href="#__codelineno-93-21"></a><span class="w"> </span>--from-literal<span class="o">=</span><span class="nv">KEY</span><span class="o">=</span>value<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-93-22" name="__codelineno-93-22" href="#__codelineno-93-22"></a><span class="w"> </span>--dry-run<span class="o">=</span>client<span class="w"> </span>-o<span class="w"> </span>yaml<span class="w"> </span>><span class="w"> </span>private/myapp-credentials.yaml
|
|
<a id="__codelineno-93-23" name="__codelineno-93-23" href="#__codelineno-93-23"></a>
|
|
<a id="__codelineno-93-24" name="__codelineno-93-24" href="#__codelineno-93-24"></a><span class="c1"># Seal secret</span>
|
|
<a id="__codelineno-93-25" name="__codelineno-93-25" href="#__codelineno-93-25"></a>kubeseal<span class="w"> </span>--format<span class="o">=</span>yaml<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-93-26" name="__codelineno-93-26" href="#__codelineno-93-26"></a><span class="w"> </span>--cert<span class="o">=</span>pub-cert.pem<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-93-27" name="__codelineno-93-27" href="#__codelineno-93-27"></a><span class="w"> </span><<span class="w"> </span>private/myapp-credentials.yaml<span class="w"> </span><span class="se">\</span>
|
|
<a id="__codelineno-93-28" name="__codelineno-93-28" href="#__codelineno-93-28"></a><span class="w"> </span>><span class="w"> </span>secrets/myapp-credentials-sealed.yaml
|
|
</code></pre></div>
|
|
<h3 id="repository-locations">Repository Locations<a class="headerlink" href="#repository-locations" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-94-1" name="__codelineno-94-1" href="#__codelineno-94-1"></a><span class="c1"># Config repository</span>
|
|
<a id="__codelineno-94-2" name="__codelineno-94-2" href="#__codelineno-94-2"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/launchpad
|
|
<a id="__codelineno-94-3" name="__codelineno-94-3" href="#__codelineno-94-3"></a>
|
|
<a id="__codelineno-94-4" name="__codelineno-94-4" href="#__codelineno-94-4"></a><span class="c1"># Helm values repository</span>
|
|
<a id="__codelineno-94-5" name="__codelineno-94-5" href="#__codelineno-94-5"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/helm-prod-values
|
|
<a id="__codelineno-94-6" name="__codelineno-94-6" href="#__codelineno-94-6"></a>
|
|
<a id="__codelineno-94-7" name="__codelineno-94-7" href="#__codelineno-94-7"></a><span class="c1"># Helm charts repository</span>
|
|
<a id="__codelineno-94-8" name="__codelineno-94-8" href="#__codelineno-94-8"></a><span class="nb">cd</span><span class="w"> </span>~/dev/k8s/forte-helm
|
|
</code></pre></div>
|
|
<h3 id="file-paths">File Paths<a class="headerlink" href="#file-paths" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-95-1" name="__codelineno-95-1" href="#__codelineno-95-1"></a><span class="c1"># New application manifest</span>
|
|
<a id="__codelineno-95-2" name="__codelineno-95-2" href="#__codelineno-95-2"></a>~/dev/k8s/launchpad/apps/myapp.yaml
|
|
<a id="__codelineno-95-3" name="__codelineno-95-3" href="#__codelineno-95-3"></a>
|
|
<a id="__codelineno-95-4" name="__codelineno-95-4" href="#__codelineno-95-4"></a><span class="c1"># Application values</span>
|
|
<a id="__codelineno-95-5" name="__codelineno-95-5" href="#__codelineno-95-5"></a>~/dev/k8s/helm-prod-values/myapp/values.yaml
|
|
<a id="__codelineno-95-6" name="__codelineno-95-6" href="#__codelineno-95-6"></a>
|
|
<a id="__codelineno-95-7" name="__codelineno-95-7" href="#__codelineno-95-7"></a><span class="c1"># Sealed secrets</span>
|
|
<a id="__codelineno-95-8" name="__codelineno-95-8" href="#__codelineno-95-8"></a>~/dev/k8s/launchpad/secrets/myapp-credentials-sealed.yaml
|
|
<a id="__codelineno-95-9" name="__codelineno-95-9" href="#__codelineno-95-9"></a>
|
|
<a id="__codelineno-95-10" name="__codelineno-95-10" href="#__codelineno-95-10"></a><span class="c1"># Plain secrets (local only)</span>
|
|
<a id="__codelineno-95-11" name="__codelineno-95-11" href="#__codelineno-95-11"></a>~/dev/k8s/launchpad/private/myapp-credentials.yaml
|
|
</code></pre></div>
|
|
<hr />
|
|
<h2 id="next-steps">Next Steps<a class="headerlink" href="#next-steps" title="Permanent link">¶</a></h2>
|
|
<p>Now that you understand the basics:</p>
|
|
<ol>
|
|
<li>✅ Deploy your first application (follow steps above)</li>
|
|
<li>📖 Read the <a href="../OPERATIONS-RUNBOOK/">Operations Runbook</a> for common tasks</li>
|
|
<li>📖 Review <a href="../REFERENCE/">Technical Reference</a> for detailed component docs</li>
|
|
<li>📖 Understand <a href="../GITOPS-ARCHITECTURE/">GitOps Architecture</a> for the big picture</li>
|
|
<li>🚀 Start contributing!</li>
|
|
</ol>
|
|
<hr />
|
|
<p><strong>Questions?</strong>
|
|
- Slack: #platform-support
|
|
- Docs: <a href="../">Full documentation index</a>
|
|
- Help: Contact platform team</p>
|
|
<p><strong>Last Updated</strong>: 2026-04-16</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</article>
|
|
</div>
|
|
|
|
|
|
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
|
</div>
|
|
|
|
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
|
|
Back to top
|
|
</button>
|
|
|
|
</main>
|
|
|
|
<footer class="md-footer">
|
|
|
|
<div class="md-footer-meta md-typeset">
|
|
<div class="md-footer-meta__inner md-grid">
|
|
<div class="md-copyright">
|
|
|
|
|
|
Made with
|
|
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
|
|
Material for MkDocs
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
</div>
|
|
<div class="md-dialog" data-md-component="dialog">
|
|
<div class="md-dialog__inner md-typeset"></div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["navigation.instant", "navigation.sections", "navigation.top", "search.highlight", "content.code.copy"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
|
|
|
|
|
|
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
|
|
|
|
|
|
</body>
|
|
</html> |