Advanced ArgoCD Deployment Patterns and Best Practices

Progressive Delivery with ArgoCD Blue-Green Deployments apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: blue-green-app spec: source: plugin: name: argocd-rollouts repoURL: https://github.com/org/app.git targetRevision: HEAD path: rollouts/ destination: server: https://kubernetes.default.svc namespace: production --- apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: blue-green-rollout spec: replicas: 3 strategy: blueGreen: activeService: active-service previewService: preview-service autoPromotionEnabled: false template: spec: containers: - name: app image: app:1.0 Multi-Cluster Management Cluster Configuration apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: multi-cluster-apps spec: generators: - clusters: {} template: metadata: name: '{{name}}-app' spec: project: default source: repoURL: https://github.com/org/app-configs.git targetRevision: HEAD path: environments/{{name}} destination: server: '{{server}}' namespace: production Sync Strategies Selective Sync apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: selective-sync-app annotations: argocd.argoproj.io/sync-wave: "5" spec: syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true - PruneLast=true - ApplyOutOfSyncOnly=true source: directory: recurse: true exclude: 'excluded-patterns/**' Production Example # Complete production deployment setup apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: production-deployment annotations: notifications.argoproj.io/subscribe.on-sync-succeeded.slack: production-deploys spec: project: production source: repoURL: https://github.com/org/production-config.git targetRevision: main path: overlays/production directory: recurse: true jsonnet: extVars: - name: environment value: production destination: server: https://kubernetes.default.svc namespace: production syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true - ServerSideApply=true retry: limit: 5 backoff: duration: 5s factor: 2 maxDuration: 3m ignoreDifferences: - group: apps kind: Deployment jsonPointers: - /spec/replicas

1 min · Me

Advanced Kubernetes Ingress Patterns and Best Practices

Core Ingress Patterns Basic HTTPS Configuration apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: secure-ingress annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" spec: tls: - hosts: - app.example.com secretName: tls-secret rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: app-service port: number: 80 Advanced Configurations 1. Path-Based Routing apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: path-based-ingress spec: rules: - host: api.example.com http: paths: - path: /v1 pathType: Prefix backend: service: name: api-v1-service port: number: 80 - path: /v2 pathType: Prefix backend: service: name: api-v2-service port: number: 80 2. Rate Limiting metadata: annotations: nginx.ingress.kubernetes.io/limit-rps: "10" nginx.ingress.kubernetes.io/limit-connections: "5" Best Practices SSL Configuration ...

1 min · Me

Automated Azure Function App Cleanup

Understanding the Need for Function App Cleanup In cloud environments, deprecated or unused resources can accumulate over time, leading to unnecessary costs and management overhead. This guide focuses on implementing automated cleanup of stopped Azure Function Apps that haven’t been active for extended periods. Identifying Inactive Function Apps First, we’ll create a PowerShell script to identify Function Apps that have been stopped for more than 45 days: Get all Function Apps in specified subscription $functionApps = Get-AzFunctionApp ...

2 min · Me

Automating macOS Setup and Backups with Homebrew, Dotfiles, and Bootstrap Scripts

Overview This guide walks through my automated macOS setup and backup workflow. The goals: Quickly set up a new Mac by running a single bootstrap script. Avoid manually remembering installed apps, preferences, and configs. Automatically back up my dotfiles and Homebrew installs to a GitHub repo. Include App Store apps, macOS preferences, and even my AirPrint printer. Core Components 1. Homebrew Bundle I use Homebrew’s brew bundle dump to capture all my brew formulas, casks, and MAS (Mac App Store) apps into a Brewfile. ...

3 min · Me

Automating Microsoft Teams Provisioning with PowerShell and Graph API

The Challenge of Teams Sprawl When organizations adopt Microsoft Teams, they often face a common challenge: how to provision Teams consistently while maintaining security standards. Manual creation leads to inconsistent settings, security gaps, and administrative overhead. This guide shows how to automate Teams provisioning with PowerShell to ensure every team follows your organization’s security baseline. Prerequisites # Install required modules Install-Module Microsoft.Graph -Scope CurrentUser Install-Module MicrosoftTeams -Scope CurrentUser # Import modules Import-Module Microsoft.Graph Import-Module MicrosoftTeams Authentication Setup # Connect to Microsoft Graph Connect-MgGraph -Scopes "Group.ReadWrite.All", "TeamSettings.ReadWrite.All", "Directory.ReadWrite.All" # Connect to Teams PowerShell Connect-MicrosoftTeams The Automation Script Core Team Creation Function Example function New-StandardizedTeam { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string]$TeamName, [Parameter(Mandatory=$true)] [string]$Description, [Parameter(Mandatory=$false)] [string[]]$Owners = @(), [Parameter(Mandatory=$false)] [string[]]$Members = @() ) try { Write-Host "Creating team: $TeamName" -ForegroundColor Yellow # Create the Microsoft 365 Group first $groupParams = @{ displayName = $TeamName description = $Description mailEnabled = $true mailNickname = ($TeamName -replace '[^a-zA-Z0-9]', '') securityEnabled = $false groupTypes = @("Unified") visibility = "Private" } $group = New-MgGroup -BodyParameter $groupParams Write-Host "Group created with ID: $($group.Id)" -ForegroundColor Green # Wait for group provisioning Start-Sleep -Seconds 10 # Convert to Team $teamParams = @{ "memberSettings" = @{ "allowCreateUpdateChannels" = $false "allowDeleteChannels" = $false "allowCreatePrivateChannels" = $false } "guestSettings" = @{ "allowCreateUpdateChannels" = $false "allowDeleteChannels" = $false } "messagingSettings" = @{ "allowUserEditMessages" = $true "allowUserDeleteMessages" = $false "allowTeamMentions" = $true "allowChannelMentions" = $true } "funSettings" = @{ "allowGiphy" = $true "giphyContentRating" = "strict" "allowStickersAndMemes" = $false "allowCustomMemes" = $false } } $team = New-MgTeam -GroupId $group.Id -BodyParameter $teamParams Write-Host "Team provisioned successfully" -ForegroundColor Green # Configure General channel Set-TeamChannelModerators -GroupId $group.Id # Add owners and members Add-TeamMembers -GroupId $group.Id -Owners $Owners -Members $Members # Hide from GAL Update-MgGroup -GroupId $group.Id -HideFromAddressLists return @{ Success = $true GroupId = $group.Id TeamName = $TeamName } } catch { Write-Error "Failed to create team: $_" return @{ Success = $false Error = $_.Exception.Message } } } Channel Configuration function Set-TeamChannelModerators { param( [Parameter(Mandatory=$true)] [string]$GroupId ) # Get the General channel $channels = Get-MgTeamChannel -TeamId $GroupId $generalChannel = $channels | Where-Object { $_.DisplayName -eq "General" } if ($generalChannel) { # Update channel to require moderation $channelParams = @{ moderationSettings = @{ userNewMessageRestriction = "everyoneExceptGuests" replyRestriction = "everyone" allowNewMessageFromBots = $true allowNewMessageFromConnectors = $true } } Update-MgTeamChannel -TeamId $GroupId -ChannelId $generalChannel.Id -BodyParameter $channelParams Write-Host "General channel moderation configured" -ForegroundColor Green } } Bulk Provisioning function Import-TeamsFromCSV { param( [Parameter(Mandatory=$true)] [string]$CsvPath ) $teams = Import-Csv -Path $CsvPath $results = @() foreach ($team in $teams) { $result = New-StandardizedTeam ` -TeamName $team.TeamName ` -Description $team.Description ` -Owners ($team.Owners -split ';') ` -Members ($team.Members -split ';') $results += $result # Rate limiting Start-Sleep -Seconds 5 } # Export results $results | Export-Csv -Path "TeamsProvisioningResults.csv" -NoTypeInformation # Summary $successful = ($results | Where-Object { $_.Success -eq $true }).Count $failed = ($results | Where-Object { $_.Success -eq $false }).Count Write-Host "Provisioning Summary:" -ForegroundColor Cyan Write-Host "Successful: $successful" -ForegroundColor Green Write-Host "Failed: $failed" -ForegroundColor Red } CSV Template TeamName,Description,Owners,Members "Marketing Team","Marketing collaboration space","admin@company.com;manager@company.com","user1@company.com;user2@company.com" "Sales Team","Sales collaboration space","admin@company.com;salesmanager@company.com","rep1@company.com;rep2@company.com" Advanced Configuration Apply Organization-Wide Settings function Set-OrganizationTeamsDefaults { # Get current policies $messagingPolicy = Get-CsTeamsMessagingPolicy -Identity Global # Update messaging policy Set-CsTeamsMessagingPolicy -Identity Global ` -AllowGiphy $true ` -GiphyRatingType "Strict" ` -AllowMemes $false ` -AllowStickers $false ` -AllowUserDeleteMessages $false ` -AllowUserEditMessages $true # Guest access configuration Set-CsTeamsGuestMessagingConfiguration ` -AllowGiphy $false ` -AllowMemes $false ` -AllowStickers $false ` -AllowUserDeleteMessages $false ` -AllowUserEditMessages $false Write-Host "Organization defaults applied" -ForegroundColor Green } Error Handling and Logging function Write-TeamsLog { param( [string]$Message, [string]$Level = "Info" ) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logEntry = "$timestamp [$Level] $Message" Add-Content -Path "TeamsProvisioning.log" -Value $logEntry switch ($Level) { "Error" { Write-Host $Message -ForegroundColor Red } "Warning" { Write-Host $Message -ForegroundColor Yellow } "Success" { Write-Host $Message -ForegroundColor Green } default { Write-Host $Message } } } Best Practices Rate Limiting: Microsoft Graph has throttling limits. Add delays between API calls. Error Recovery: Implement retry logic for transient failures. Validation: Verify team settings post-creation. Documentation: Maintain a log of all provisioned teams. Regular Audits: Schedule periodic reviews of team settings. Conclusion Automating Teams provisioning ensures consistency, improves security posture, and reduces administrative overhead. This approach scales from small deployments to enterprise-wide migrations while maintaining your organization’s governance standards. ...

4 min · Me