Skip to content

Commit 32b800a

Browse files
authored
Merge pull request #2898 from DougAnsonAustinTX/trivy-techreview-1
Trivy techreview
2 parents 0c14f81 + a3602c4 commit 32b800a

5 files changed

Lines changed: 163 additions & 86 deletions

File tree

content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/_index.md

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
11
---
2-
title: Secure Multi-Architecture Containers with Trivy on Azure Cobalt 100 (Arm64)
3-
4-
draft: true
5-
cascade:
6-
draft: true
2+
title: Scan multi-architecture containers with Trivy on Azure Cobalt 100
73

84
minutes_to_complete: 45
95

10-
who_is_this_for: This learning path is designed for developers and DevOps engineers who want to integrate security scanning into CI/CD pipelines for multi-architecture container images.
6+
who_is_this_for: This learning path is for developers and DevOps engineers who want to integrate security scanning into CI/CD pipelines for multi-architecture container images.
117

128
learning_objectives:
13-
- Provision an Azure Arm64 virtual machine using Azure console, with Ubuntu Pro 24.04 LTS as the base image
14-
- Build multi-architecture (amd64/arm64) container images for Azure Cobalt 100
15-
- Install and configure Trivy on Arm64 Ubuntu systems
16-
- Scan container images for vulnerabilities locally and in CI
17-
- Configure self-hosted GitHub Actions Arm runners
18-
- Enforce security gates in CI/CD pipelines based on vulnerability severity
19-
- Generate and analyze JSON reports for compliance and audit purposes
9+
- Build and scan multi-architecture container images using Trivy on Azure Cobalt 100
10+
- Configure self-hosted GitHub Actions Arm runners for CI/CD pipelines
11+
- Enforce security gates in CI pipelines based on vulnerability severity
2012

2113
prerequisites:
2214
- A [Microsoft Azure](https://azure.microsoft.com/) account with access to Cobalt 100 based instances (Dpsv6)

content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/background.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,17 @@ To learn more, see the Microsoft blog [Announcing the preview of new Azure virtu
1414

1515
## Trivy
1616

17-
Trivy is an open-source vulnerability scanner designed to detect security issues in container images, filesystems, and infrastructure configurations. It is widely used in modern DevSecOps workflows to identify known vulnerabilities in operating system packages and application dependencies.
17+
Trivy is an open-source vulnerability scanner designed to detect security issues in container images, filesystems, and infrastructure configurations. It's widely used in modern DevSecOps workflows to identify known vulnerabilities in operating system packages and application dependencies.
1818

1919
You can use Trivy to perform fast and reliable security scans on container images built for multiple architectures, including Arm64. It helps teams shift security left by detecting vulnerabilities early in the development and CI/CD pipeline.
2020

2121
Learn more at the [Trivy official website](https://trivy.dev/) and in the [Trivy documentation](https://trivy.dev/docs/).
22+
23+
## What you've accomplished and what's next
24+
25+
You now understand the core technologies in this Learning Path:
26+
27+
- Azure Cobalt 100, Microsoft's first-generation Arm-based processor built on Neoverse-N2 architecture
28+
- Trivy, an open-source security scanner for detecting vulnerabilities in container images
29+
30+
Next, you'll create an Azure Cobalt 100 virtual machine to begin building and scanning multi-architecture container images.

content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/instance.md

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,47 +20,61 @@ This Learning Path focuses on general-purpose virtual machines in the Dpsv6 seri
2020

2121
While the steps to create this instance are included here for convenience, you can also refer to the [Deploy a Cobalt 100 virtual machine on Azure Learning Path](/learning-paths/servers-and-cloud-computing/cobalt/).
2222

23-
## Create an Arm-based Azure virtual machine
23+
## Create an Arm-based Azure virtual machine
2424

25-
Creating a virtual machine based on Azure Cobalt 100 is no different to creating any other virtual machine in Azure. Follow the steps below to create an Azure virtual machine:
25+
Creating a virtual machine based on Azure Cobalt 100 is no different to creating any other virtual machine in Azure. To create an Azure virtual machine:
2626

2727
- Launch the Azure portal and navigate to **Virtual Machines**.
2828
- Select **Create**, and select **Virtual Machine** from the drop-down list.
2929
- Inside the **Basic** tab, fill in the instance details such as **Virtual machine name** and **Region**.
3030
- Select the image for your virtual machine (for example, Ubuntu Pro 24.04 LTS) and select **Arm64** as the VM architecture.
31-
- In the **Size** field, select **See all sizes** and select the D-Series v6 family of virtual machines.
31+
- In the **Size** field, select **See all sizes** and select the D-Series v6 family of virtual machines.
3232
- Select **D4ps_v6** from the list as shown in the diagram below:
3333

34-
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/instance.png "Select the D-Series v6 family of virtual machines")
34+
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6)#center](images/instance.png "Select the D-Series v6 family of virtual machines")
3535

36-
- For **Authentication type**, select **SSH public key**. {{% notice Note %}}
36+
- For **Authentication type**, select **SSH public key**.
37+
38+
{{% notice Note %}}
3739
Azure generates an SSH key pair for you and lets you save it for future use. This method is fast, secure, and easy for connecting to your virtual machine.
3840
{{% /notice %}}
41+
3942
- Fill in the **Administrator username** for your VM.
40-
- Select **Generate new key pair**, and select **RSA SSH Format** as the SSH Key Type. {{% notice Note %}}
43+
- Select **Generate new key pair**, and select **RSA SSH Format** as the SSH Key Type.
44+
45+
{{% notice Note %}}
4146
RSA offers better security with keys longer than 3072 bits.
42-
{{% /notice %}}
47+
{{% /notice %}}
48+
4349
- Give your SSH key a key pair name.
4450
- In the **Inbound port rules**, select **HTTP (80)** and **SSH (22)** as the inbound ports, as shown below:
4551

46-
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/instance1.png "Allow inbound port rules")
52+
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6)#center](images/instance1.png "Allow inbound port rules")
4753

4854
- Now select the **Review + Create** tab and review the configuration for your virtual machine. It should look like the following:
4955

50-
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/ubuntu-pro.png "Review and create an Azure Cobalt 100 Arm64 VM")
56+
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6)#center](images/ubuntu-pro.png "Review and create an Azure Cobalt 100 Arm64 VM")
5157

5258
- When you are happy with your selection, select the **Create** button and then **Download Private key and Create Resource** button.
5359

54-
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/instance4.png "Download private key and create resource")
60+
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6)#center](images/instance4.png "Download private key and create resource")
5561

5662
Your virtual machine should be ready and running in a few minutes. You can SSH into the virtual machine using the private key, along with the public IP details.
5763

58-
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/final-vm.png "VM deployment confirmation in Azure portal")
64+
![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6)#center](images/final-vm.png "VM deployment confirmation in Azure portal")
5965

6066
{{% notice Note %}}
6167

6268
To learn more about Arm-based virtual machine in Azure, see “Getting Started with Microsoft Azure” in [Get started with Arm-based cloud instances](/learning-paths/servers-and-cloud-computing/csp/azure).
6369

6470
{{% /notice %}}
6571

66-
Your Azure Cobalt 100 Arm64 virtual machine is now ready. Continue to the next step to install and configure Trivy.
72+
## What you've accomplished and what's next
73+
74+
You've successfully:
75+
76+
- Created an Azure Cobalt 100 Arm-based virtual machine using the D-Series v6 (Dpsv6) family
77+
- Selected Ubuntu Pro 24.04 LTS as the operating system
78+
- Configured SSH authentication for secure access
79+
80+
Your Azure Cobalt 100 Arm64 virtual machine is now ready. Next, you'll build and scan multi-architecture container images using Docker and Trivy.

content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/trivy-ci-integration.md

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ You will move from local scanning to fully automated security enforcement in CI.
2727
Ensure that you have:
2828

2929
- Completed the local Trivy scanning module
30-
- A GitHub repository
30+
- Created a GitHub account and are able to log into it.
31+
- Created a Docker hub account and are able to log into it.
3132
- An Azure Cobalt 100 Arm64 Ubuntu VM running
3233
- A multi-architecture container image pushed to Docker Hub
3334

@@ -36,19 +37,19 @@ These components are required for building a secure CI pipeline.
3637

3738
## Create a New GitHub Repository
3839

39-
Open in your browser: https://github.com/new
40+
Open in your browser: [https://github.com/new](https://github.com/new)
4041

4142
**Fill in:**
4243

43-
- Repository name: trivy-arm-ci-demo (or any name you prefer)
44+
- Repository name: **trivy-arm-ci-demo**
4445
- Visibility: Public or Private
4546
- Do NOT initialize with README (keep it empty)
4647

4748
**Click:**
4849

4950
- Create repository
5051

51-
You now have an empty GitHub repository ready to receive your project files.
52+
You now have an empty GitHub repository ready to receive your project files. Next lets push our local repo up to github.com.
5253

5354
## Initialize Git Repository Locally
5455

@@ -67,19 +68,22 @@ Turns your local project folder into a Git repository.
6768
git add .
6869
git commit -m "Multi-arch nginx image for Trivy scan"
6970
```
71+
7072
Stage and save your Dockerfile and demo files into Git history.
7173

7274
**Link Local Repo to GitHub:**
7375

76+
Link your local repo to your github.com repo that you have created. Replace <YOUR_GITHUB_USERNAME> with your GitHub username:
77+
7478
```bash
7579
git branch -M main
7680
git remote add origin https://github.com/<YOUR_GITHUB_USERNAME>/trivy-arm-ci-demo.git
7781
```
7882

79-
You can connect your local repository to the remote GitHub repository.
80-
8183
**Push Code to GitHub:**
8284

85+
Finally, push your local repo up to github.com:
86+
8387
```bash
8488
git push -u origin main
8589
```
@@ -88,7 +92,7 @@ Uploads your project files to GitHub and sets the main branch for future pushes.
8892

8993
## Setup GitHub Actions Arm Runner
9094

91-
Navigate in GitHub:
95+
Navigate in the github.com dashboard for your newly created repo:
9296

9397
```text
9498
Settings → Actions → Runners → Add Runner
@@ -102,12 +106,16 @@ GitHub will display setup commands.
102106

103107
This prepares GitHub to register a self-hosted Arm64 runner.
104108

105-
![GitHub Actions Arm64 self-hosted runner connected alt-txt#center](images/arm64-runner.png "Arm64 GitHub Runner Status")
109+
![GitHub Actions Arm64 self-hosted runner connected#center](images/arm64-runner.png "Arm64 GitHub Runner Status")
110+
111+
Lets step through the steps outlined by the GitHub self-hosted runner setup has provided.
106112

107113
## Create Runner Directory on VM
108114

109115
Create a workspace for the GitHub runner software.
116+
110117
```bash
118+
cd $HOME
111119
mkdir actions-runner
112120
cd actions-runner
113121
```
@@ -119,19 +127,25 @@ Use the download command provided by GitHub:
119127
```bash
120128
curl -o actions-runner-linux-arm64.tar.gz -L https://github.com/actions/runner/releases/download/v2.331.0/actions-runner-linux-arm64-2.331.0.tar.gz
121129
tar xzf actions-runner-linux-arm64.tar.gz
130+
rm ./actions-runner-linux-arm64.tar.gz
122131
```
132+
123133
Downloads and extracts the Arm64-compatible runner.
124134

125135
**Configure Runner:**
126136

137+
Run the configuration script to configure the Runner. This command is also shown in the GitHub runner setup page and can be simply copied/pasted:
138+
127139
```bash
128140
./config.sh --url https://github.com/<USERNAME>/<REPO> --token <TOKEN>
129141
```
130142

131-
Registers the runner with your GitHub repository.
143+
Press "Enter" when asked during the configuration steps to choose the defaults.
132144

133145
**Start Runner:**
134146

147+
Lets run the runner now!
148+
135149
```bash
136150
./run.sh
137151
```
@@ -147,34 +161,31 @@ Current runner version: '2.331.0'
147161

148162
**In your GitHub repository:**
149163

150-
```text
151-
Settings → Secrets → Actions → New repository secret
164+
```text
165+
Settings → Secrets and Variables → Actions → New repository secret
152166
```
153-
Add the following secrets:
154167

155-
| Name | Value |
156-
| ----------------- | ----------------------------------- |
157-
| `DOCKER_USERNAME` | Your Docker Hub username |
158-
| `DOCKER_PASSWORD` | Docker Hub password or access token |
159-
| `IMAGE_NAME` | trivy-multiarch-nginx |
160-
| `IMAGE_TAG` | latest |
168+
Add the following secrets using your Docker Hub username Docker Hub generated personal access token with "RO" authorization:
169+
170+
| Name | Value |
171+
| ----------------- | -------------------------------- |
172+
| `DOCKER_USERNAME` | Your Docker Hub username |
173+
| `DOCKER_PASSWORD` | Docker Hub personal access token |
174+
| `IMAGE_NAME` | trivy-multiarch-nginx |
175+
| `IMAGE_TAG` | latest |
161176

162-
![GitHub Actions secrets configuration alt-txt#center](images/secrets.png "GitHub Secrets Configuration")
177+
![GitHub Actions secrets configuration#center](images/secrets.png "GitHub Secrets Configuration")
163178

164179
## Create CI Workflow
165-
Create Workflow Directory
166180

167-
```bash
168-
mkdir -p .github/workflows
169-
```
170-
**Create file:**
181+
In an additional SSH shell, create a Workflow directory:
171182

172183
```bash
173-
nano .github/workflows/trivy-scan.yml
184+
mkdir -p $HOME/trivy-multiarch-demo/.github/workflows
185+
cd $HOME/trivy-multiarch-demo
174186
```
175187

176-
Add:
177-
Defines a CI pipeline that scans images on every push.
188+
Edit a file named **$HOME/trivy-multiarch-demo/.github/workflows/trivy-scan.yml** with the following content:
178189

179190
```yaml
180191
name: Trivy Scan on Arm Runner
@@ -233,11 +244,18 @@ git add .
233244
git commit -m "Add Trivy scan on Arm runner"
234245
git push origin main
235246
```
236-
Push triggers GitHub Actions automatically.
247+
248+
Push triggers GitHub Actions automatically. You should also see output from the ./run.sh command running in the other SSH shell that resembles:
249+
250+
```output
251+
026-02-17 16:09:52Z: Listening for Jobs
252+
2026-02-17 16:15:27Z: Running job: security-scan
253+
2026-02-17 16:15:35Z: Job security-scan completed with result: Failed
254+
```
237255

238256
## Verify CI Execution (Trivy Security Gate on Arm Runner)
239257

240-
After pushing your code to GitHub, navigate to:
258+
After pushing your code to GitHub, on the github web dashboard, navigate to:
241259

242260
```text
243261
GitHub → Actions → Trivy Scan on Arm Runner
@@ -247,7 +265,7 @@ Select the latest workflow run.
247265

248266
Expected Results:
249267

250-
![GitHub Actions Trivy security scan workflow execution log alt-txt#center](images/security-scan.png "Trivy CI Security Scan Execution")
268+
![GitHub Actions Trivy security scan workflow execution log#center](images/security-scan.png "Trivy CI Security Scan Execution")
251269

252270
You should observe the following:
253271

@@ -282,33 +300,47 @@ This means:
282300
This is known as a security gate.
283301

284302
## Understanding the CI Scan Result
285-
Is This Behavior Good or Bad?
286303

287-
- This behavior is GOOD and expected in real-world CI/CD pipelines
304+
### Is This Behavior Good or Bad?
305+
306+
This behavior is GOOD and expected in real-world CI/CD pipelines.
288307

289308
Modern DevSecOps practices integrate security tools like Trivy directly into Continuous Integration to automatically detect vulnerabilities.
290309

291310
The pipeline is designed to:
292311

293312
- Stop insecure container images early in the development lifecycle
294-
-Prevent vulnerable software from reaching staging or production environments
313+
- Prevent vulnerable software from reaching staging or production environments
295314
- Enforce security and compliance policies automatically
296315

297-
**What a Failing Pipeline Means**
316+
### What a Failing Pipeline Means
298317

299318
When the Trivy scan fails the job:
300319

301320
- Trivy successfully detected HIGH or CRITICAL vulnerabilities in the container image
302321
- The security gate blocked the insecure image
303322
- The CI pipeline protected downstream environments
304323

305-
**Why This Matters in Enterprise CI/CD**
324+
### Why This Matters in Enterprise CI/CD
306325

307326
In enterprise environments, automated security enforcement is mandatory.
308327

309-
- Failing fast on vulnerabilities ensures:
328+
Failing fast on vulnerabilities ensures:
329+
310330
- Faster remediation
311331
- Reduced security risk
312332
- Strong compliance posture
313333

314334
This behavior confirms that your Arm-based CI pipeline is working correctly.
335+
336+
## What you've accomplished and what's next
337+
338+
You've successfully:
339+
340+
- Set up a self-hosted GitHub Actions runner on Azure Cobalt 100 Arm64
341+
- Configured GitHub secrets for secure authentication
342+
- Created a CI/CD pipeline that automatically scans container images with Trivy
343+
- Implemented security gates that fail builds when HIGH or CRITICAL vulnerabilities are detected
344+
- Generated and uploaded vulnerability reports as CI artifacts
345+
346+
You now have a complete DevSecOps workflow that runs natively on Arm infrastructure. This setup enables you to shift security left in your development process, catching vulnerabilities before they reach production environments. You can extend this workflow by adding remediation steps, integrating with notification systems, or customizing the security policies to match your organization's requirements.

0 commit comments

Comments
 (0)