Skip to content

Commit 28d03ee

Browse files
authored
Merge pull request #30 from thomast1906/updates-may-2025
Updates may 2025
2 parents cd07e2a + a7138ac commit 28d03ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1431
-166
lines changed

.github/workflows/main.yml

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,55 @@ jobs:
1313
terraform:
1414
name: Terrform-Deploy
1515
runs-on: ubuntu-latest
16-
defaults:
17-
run:
18-
working-directory: "./2-Terraform-AZURE-Services-Creation/4-aks"
1916
permissions:
2017
contents: write
18+
id-token: write # Required for OIDC
19+
2120
env:
2221
ARM_CLIENT_ID: ${{ secrets.AZURE_AD_CLIENT_ID }}
23-
ARM_CLIENT_SECRET: ${{ secrets.AZURE_AD_CLIENT_SECRET }}
2422
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
2523
ARM_TENANT_ID: ${{ secrets.AZURE_AD_TENANT_ID }}
24+
ARM_USE_OIDC: true
2625
tf_resource_group_name: "thomasthorntoncloud"
2726
tf_storage_account_name: "thomasthorntontfstate"
2827
tf_state_container: "devopsthehardwaygithub"
2928
tf_state_key: "terraform.tfstate"
3029

30+
3131
steps:
3232
- name: Checkout Code
3333
uses: actions/checkout@v4
3434

3535
- name: Setup Terraform
3636
uses: hashicorp/setup-terraform@v3
3737
with:
38-
terraform_version: 1.9.6
38+
terraform_version: 1.11.0
3939
terraform_wrapper: true
4040

41+
# Add in tutorial 6-Terarform-Docs
42+
# - name: Render terraform docs and push changes back to PR
43+
# uses: terraform-docs/gh-actions@main
44+
# with:
45+
# working-dir: ./2-Terraform-AZURE-Services-Creation/1-acr, ./2-Terraform-AZURE-Services-Creation/2-vnet, ./2-Terraform-AZURE-Services-Creation/3-log-analytics, ./2-Terraform-AZURE-Services-Creation/4-aks
46+
# output-file: README.md
47+
# output-method: inject
48+
# git-push: "true"
4149

4250
- name: Terraform Init
4351
run: terraform init
52+
working-directory: ./2-Terraform-AZURE-Services-Creation/4-aks
53+
54+
# Add in tutorial 5-Terraform-Static-Code-Analysis
55+
# - name: tfsec
56+
# uses: aquasecurity/[email protected]
57+
# with:
58+
# tfsec_args: --soft-fail
59+
# github_token: ${{ github.token }}
4460

4561
- name: Terraform Format
4662
if: github.event_name == 'pull_request'
4763
run: terraform fmt
64+
working-directory: ./2-Terraform-AZURE-Services-Creation/4-aks
4865

4966
- name: Auto Commit Changes
5067
uses: stefanzweifel/git-auto-commit-action@v5
@@ -56,9 +73,11 @@ jobs:
5673

5774
- name: Terraform Plan
5875
run: terraform plan -no-color -input=false
76+
working-directory: ./2-Terraform-AZURE-Services-Creation/4-aks
5977
env:
6078
DEPLOYMENT_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
6179

6280
- name: Terraform Apply
6381
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
64-
run: terraform apply -auto-approve -input=false
82+
run: terraform apply -auto-approve -input=false
83+
working-directory: ./2-Terraform-AZURE-Services-Creation/4-aks

1-Azure/1-Configure-Terraform-Remote-Storage.md

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ In this lab, you'll create a secure location to store the remote Terraform State
66
## 🛠️ Create Blob Storage for Terraform State File
77

88
### Prerequisites
9-
- [ ] Azure CLI installed and configured
9+
- [ ] Azure CLI installed and configured (`az login` executed)
10+
- [ ] Contributor permissions on your Azure subscription
1011
- [ ] Basic understanding of Azure Storage concepts
1112

1213
### Steps
@@ -27,14 +28,18 @@ In this lab, you'll create a secure location to store the remote Terraform State
2728
- Run the following command in your terminal:
2829

2930
```bash
30-
./scripts/create-terraform-storage.sh
31+
./scripts/1-create-terraform-storage.sh
3132
```
3233

3334
3. **What's Happening Behind the Scenes?**
3435
The script performs these actions:
35-
- [ ] Creates an Azure Resource Group
36-
- [ ] Sets up an Azure Storage Account
36+
- [ ] Creates an Azure Resource Group with appropriate tags
37+
- [ ] Sets up an Azure Storage Account with enhanced security settings:
38+
- Encryption enabled for blob storage
39+
- TLS 1.2 enforced
40+
- Public access to blobs disabled
3741
- [ ] Establishes an Azure Blob storage container
42+
- [ ] Outputs configuration for your Terraform backend
3843
3944
## 🔍 Verification
4045
To ensure everything was set up correctly:
@@ -54,4 +59,17 @@ After running the script, try to answer these questions:
5459
3. How would you access this state file in your Terraform configurations?
5560
5661
## 💡 Pro Tip
57-
Consider setting up access policies and encryption for your storage account to enhance security. Azure provides several options for this, including Azure AD authentication and Azure Key Vault integration.
62+
Consider implementing these additional security measures for production environments:
63+
1. Enable soft delete and versioning for your blob storage to protect against accidental deletion
64+
2. Set up a resource lock to prevent accidental deletion of the storage account
65+
3. Use Managed Identities instead of storage account keys for authentication
66+
4. Configure network rules to restrict access to specific networks
67+
5. Set up Azure Key Vault to store sensitive backend configuration
68+
69+
Example of adding a resource lock:
70+
```bash
71+
az lock create --name LockTerraformStorage --lock-type CanNotDelete \
72+
--resource-group devopshardway-rg \
73+
--resource-name devopshardwaysa \
74+
--resource-type Microsoft.Storage/storageAccounts
75+
```
Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,41 @@
11
# Create Azure AD Group for AKS Admins
22

33
## 🎯 Purpose
4+
45
In this lab, you'll create an Azure AD Group for AKS Admins. These "admins" will be the designated users who can access the AKS cluster using kubectl.
56

67
## 🛠️ Create Azure AD AKS Admin Group
78

89
### Prerequisites
9-
- [ ] Sufficient permissions to create Azure AD groups
1010

11+
- [ ] Azure CLI installed and configured (`az login` executed)
12+
- [ ] Sufficient permissions to create Azure AD groups (e.g., Global Administrator or User Administrator role)
1113

1214
### Steps
1315

1416
1. **Run the Script**
17+
1518
Execute the following command in your terminal:
19+
1620
```bash
17-
./scripts/create-azure-ad-group.sh
21+
./scripts/2-create-azure-ad-group.sh
1822
```
1923
2. What the Script Does
2024

2125
The script performs these actions:
22-
- [ ] Creates an Azure AD Group named `devopsthehardway-aks-group`
23-
- [ ] Adds the current user (logged into Az CLI) to the `devopsthehardway-aks-group`
24-
- [ ] Outputs the Azure AD Group ID
26+
27+
- [ ] Creates an Azure AD Group named `devopsthehardway-aks-group` with a descriptive purpose
28+
- [ ] Adds the current user (logged into Az CLI) to the `devopsthehardway-aks-group`
29+
- [ ] Outputs the Azure AD Group ID in a clear, formatted way for later use
2530

2631
**Important Note**
27-
Make sure to note down the Azure AD Group ID displayed at the end of the script execution. You'll need this for AKS Terraform configurations later.
32+
33+
Make sure to save the Azure AD Group ID displayed at the end of the script execution. You'll need this for AKS Terraform configurations in the following sections.
2834

2935
## 🔍 Verification
36+
3037
To ensure the group was created successfully:
38+
3139
1. Log into the [Azure Portal](https://portal.azure.com)
3240
2. Navigate to **Azure Active Directory > Groups**
3341
3. Search for `devopsthehardway-aks-group`
@@ -36,10 +44,28 @@ To ensure the group was created successfully:
3644
![](images/azure-ad-group.png)
3745

3846
## 🧠 Knowledge Check
47+
3948
After running the script, consider these questions:
49+
4050
1. Why is it beneficial to use Azure AD groups for AKS admin access?
4151
2. How does this group-based access improve security compared to individual user access?
4252
3. In what ways might you further modify the AD group for different levels of access?
4353

4454
## 💡 Pro Tip
45-
Consider setting up multiple AD groups with different levels of access (e.g., read-only, developer, admin) to implement a more granular access control strategy for your AKS clusters.
55+
56+
Consider implementing these best practices for production environments:
57+
58+
1. Create multiple AD groups with different levels of access (e.g., read-only, developer, admin)
59+
2. Integrate with Privileged Identity Management (PIM) for just-in-time access
60+
3. Implement regular access reviews to ensure appropriate access
61+
4. Use Conditional Access policies to enforce multi-factor authentication
62+
63+
Example of adding another user to the group:
64+
65+
```bash
66+
# Get object ID of user to add
67+
USER_OBJECTID=$(az ad user show --id [email protected] --query id -o tsv)
68+
69+
# Add user to the AKS admin group
70+
az ad group member add --group devopsthehardway-aks-group --member-id $USER_OBJECTID
71+
```

1-Azure/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Azure Setup for DevOps The Hard Way
2+
3+
## Overview
4+
This directory contains the foundational Azure setup needed for the DevOps The Hard Way - Azure project. These steps establish the core Azure resources that will be used throughout the tutorial.
5+
6+
## Labs in this Section
7+
8+
### [1. Configure Terraform Remote Storage](./1-Configure-Terraform-Remote-Storage.md)
9+
Set up an Azure Storage Account to securely store your Terraform state files, which is essential for team collaboration and state management.
10+
11+
### [2. Create Azure AD Group for AKS Admins](./2-Create-Azure-AD-Group-AKS-Admins.md)
12+
Create an Azure Active Directory group to manage administrative access to your Kubernetes clusters with proper RBAC controls.
13+
14+
## Scripts
15+
16+
The `scripts` directory contains shell scripts that automate the setup process:
17+
18+
- [`create-terraform-storage.sh`](./scripts/create-terraform-storage.sh): Creates a resource group, storage account, and blob container for Terraform state
19+
- [`create-azure-ad-group.sh`](./scripts/create-azure-ad-group.sh): Creates an Azure AD Group for AKS administrators
20+
21+
## Pre-requisites
22+
23+
Before starting these labs, ensure you have:
24+
25+
1. An Azure account with appropriate permissions
26+
2. Azure CLI installed and configured (`az login`)
27+
3. Basic familiarity with Azure services and Terraform concepts
28+
29+
## Best Practices Applied
30+
31+
- Resource naming conventions
32+
- Security-enhanced storage configuration
33+
- RBAC-based access control
34+
- Infrastructure as Code for reproducibility
35+
- Proper error handling in scripts
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/bin/sh
2+
3+
# Configuration
4+
RESOURCE_GROUP_NAME="devopshardway-rg"
5+
STORAGE_ACCOUNT_NAME="devopshardwaysa"
6+
LOCATION="uksouth"
7+
CONTAINER_NAME="tfstate"
8+
9+
# Error handling function
10+
handle_error() {
11+
echo "ERROR: $1"
12+
exit 1
13+
}
14+
15+
# Verify Azure CLI is installed and user is logged in
16+
if ! command -v az &> /dev/null; then
17+
handle_error "Azure CLI is not installed. Please install it first: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"
18+
fi
19+
20+
# Check if user is logged in
21+
echo "Verifying Azure CLI login status..."
22+
az account show &> /dev/null || handle_error "You are not logged in to Azure CLI. Please run 'az login' first."
23+
24+
# Check if Resource Group exists
25+
echo "Checking if resource group $RESOURCE_GROUP_NAME exists..."
26+
RESOURCE_GROUP_EXISTS=$(az group exists --name $RESOURCE_GROUP_NAME)
27+
28+
if [ "$RESOURCE_GROUP_EXISTS" = "true" ]; then
29+
echo "Resource group $RESOURCE_GROUP_NAME already exists."
30+
else
31+
# Create Resource Group
32+
echo "Creating resource group $RESOURCE_GROUP_NAME in $LOCATION..."
33+
az group create -l $LOCATION -n $RESOURCE_GROUP_NAME --tags "Purpose=azure-devops-hardway" || handle_error "Failed to create resource group"
34+
fi
35+
36+
# Check if Storage Account exists
37+
echo "Checking if storage account $STORAGE_ACCOUNT_NAME exists..."
38+
STORAGE_ACCOUNT_EXISTS=$(az storage account check-name --name $STORAGE_ACCOUNT_NAME --query 'nameAvailable' --output tsv)
39+
40+
if [ "$STORAGE_ACCOUNT_EXISTS" = "false" ]; then
41+
echo "Storage account $STORAGE_ACCOUNT_NAME is already created in resource group $RESOURCE_GROUP_NAME."
42+
else
43+
# Create Storage Account with improved security settings
44+
echo "Creating storage account $STORAGE_ACCOUNT_NAME..."
45+
az storage account create \
46+
-n $STORAGE_ACCOUNT_NAME \
47+
-g $RESOURCE_GROUP_NAME \
48+
-l $LOCATION \
49+
--sku Standard_LRS \
50+
--encryption-services blob \
51+
--min-tls-version TLS1_2 \
52+
--allow-blob-public-access false \
53+
--tags "Purpose=azure-devops-hardway" || handle_error "Failed to create storage account"
54+
55+
# Create Storage Account blob container
56+
echo "Creating blob container $CONTAINER_NAME..."
57+
az storage container create \
58+
--name $CONTAINER_NAME \
59+
--account-name $STORAGE_ACCOUNT_NAME \
60+
--auth-mode login || handle_error "Failed to create blob container"
61+
62+
# Output the access key (in a real environment, consider using managed identities instead)
63+
echo "Retrieving storage account key..."
64+
ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
65+
66+
echo "Configuration for terraform backend:"
67+
echo "terraform {"
68+
echo " backend \"azurerm\" {"
69+
echo " resource_group_name = \"$RESOURCE_GROUP_NAME\""
70+
echo " storage_account_name = \"$STORAGE_ACCOUNT_NAME\""
71+
echo " container_name = \"$CONTAINER_NAME\""
72+
echo " key = \"terraform.tfstate\""
73+
echo " }"
74+
echo "}"
75+
76+
echo "Setup complete!"
77+
fi
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/bin/sh
2+
3+
# Configuration
4+
AZURE_AD_GROUP_NAME="devopsthehardway-aks-group"
5+
6+
# Error handling function
7+
handle_error() {
8+
echo "ERROR: $1"
9+
exit 1
10+
}
11+
12+
# Verify Azure CLI is installed and user is logged in
13+
if ! command -v az &> /dev/null; then
14+
handle_error "Azure CLI is not installed. Please install it first: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"
15+
fi
16+
17+
# Check if user is logged in
18+
echo "Verifying Azure CLI login status..."
19+
az account show &> /dev/null || handle_error "You are not logged in to Azure CLI. Please run 'az login' first."
20+
21+
echo "Retrieving current user Object ID..."
22+
CURRENT_USER_OBJECTID=$(az ad signed-in-user show --query id -o tsv) || handle_error "Failed to retrieve current user Object ID"
23+
24+
# Check if Azure AD Group exists
25+
echo "Checking if Azure AD Group $AZURE_AD_GROUP_NAME exists..."
26+
GROUP_EXISTS=$(az ad group list --filter "displayName eq '$AZURE_AD_GROUP_NAME'" --query "[].displayName" -o tsv)
27+
28+
if [ "$GROUP_EXISTS" = "$AZURE_AD_GROUP_NAME" ]; then
29+
echo "Azure AD group $AZURE_AD_GROUP_NAME already exists."
30+
else
31+
# Create Azure AD Group with description
32+
echo "Creating Azure AD group $AZURE_AD_GROUP_NAME..."
33+
az ad group create \
34+
--display-name $AZURE_AD_GROUP_NAME \
35+
--mail-nickname $AZURE_AD_GROUP_NAME \
36+
--description "Administrators for AKS clusters with full kubectl access" || handle_error "Failed to create Azure AD group"
37+
fi
38+
39+
# Check if Current User is already a member of the Azure AD Group
40+
echo "Checking if current user is a member of $AZURE_AD_GROUP_NAME..."
41+
USER_IN_GROUP=$(az ad group member check --group $AZURE_AD_GROUP_NAME --member-id $CURRENT_USER_OBJECTID --query value -o tsv)
42+
43+
if [ "$USER_IN_GROUP" = "true" ]; then
44+
echo "Current user is already a member of the Azure AD group $AZURE_AD_GROUP_NAME."
45+
else
46+
# Add Current az login user to Azure AD Group
47+
echo "Adding current user to Azure AD group $AZURE_AD_GROUP_NAME..."
48+
az ad group member add --group $AZURE_AD_GROUP_NAME --member-id $CURRENT_USER_OBJECTID || handle_error "Failed to add current user to Azure AD group"
49+
fi
50+
51+
echo "Retrieving Azure AD Group ID..."
52+
AZURE_GROUP_ID=$(az ad group show --group $AZURE_AD_GROUP_NAME --query id -o tsv) || handle_error "Failed to retrieve Azure AD Group ID"
53+
54+
echo "✅ Setup complete!"
55+
echo "==========================================================================="
56+
echo " AZURE AD GROUP ID: $AZURE_GROUP_ID"
57+
echo " You'll need this ID for AKS Terraform configurations"
58+
echo "==========================================================================="

0 commit comments

Comments
 (0)