Skip to content

Commit 4d2e46b

Browse files
e-minguezairadier
andauthored
Added Azure pipelines example (#24)
* Added Azure pipelines example * Update docs/index.md Co-authored-by: Álvaro Iradier <airadier@gmail.com> Co-authored-by: Álvaro Iradier <airadier@gmail.com>
1 parent 0fac090 commit 4d2e46b

File tree

7 files changed

+165
-0
lines changed

7 files changed

+165
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
love/love
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Azure Pipelines Demo
2+
3+
In this demo we will use Azure Pipelines to build, scan and push a container image.
4+
5+
NOTE: This example uses the [new Sysdig scanning engine](https://docs.sysdig.com/en/docs/sysdig-secure/scanning/new-scanning-engine/)
6+
7+
The workflow is as follows:
8+
9+
1. Build the container image and store it locally
10+
2. Download the sysdig-cli-scanner cli if needed
11+
3. Perform the scan
12+
4. Push the container image to a remote registry
13+
14+
The workflow leverages Azure Pipeline actions cache to avoid downloading the binary,
15+
the databases and the container images if they are available.
16+
17+
## Setup
18+
19+
### Variables
20+
21+
It is required to create a TOKEN pipeline variable containing the Sysdig API token in order
22+
to be able to perform the scan. See [the official documentation](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/set-secret-variables)
23+
for instructions on how to do it, but basically:
24+
25+
* Edit the pipeline
26+
* Select "Variables"
27+
* Add a new TOKEN variable with the proper content
28+
29+
### Registry access
30+
31+
It is required to create a Docker registry "Service Connections" to be able to push images to the registry.
32+
See [the official documentation](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#docker-hub-or-others)
33+
for instructions on how to do it, but basically:
34+
35+
* Select Project settings > Service connections
36+
* Select + New service connection, select the "Docker Registry", and then select Next
37+
* Add the registry url, user & password and a Service connection name (it will be used as REGISTRY_CONNECTION)
38+
39+
Then, modify the variables on the [azure-pipelines.yml](azure-pipelines.yml) file to fit your needs:
40+
41+
```
42+
SYSDIG_SECURE_ENDPOINT: "https://eu1.app.sysdig.com"
43+
REGISTRY_HOST: "quay.io"
44+
IMAGE_NAME: "e_minguez/my-example-app"
45+
IMAGE_TAG: "latest"
46+
REGISTRY_CONNECTION: "quayio-e_minguez"
47+
```
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
trigger:
2+
- main
3+
4+
pool:
5+
vmImage: ubuntu-latest
6+
7+
variables:
8+
CACHE_FOLDER: $(Pipeline.Workspace)/cache/
9+
SYSDIG_SECURE_ENDPOINT: "https://eu1.app.sysdig.com"
10+
REGISTRY_HOST: "quay.io"
11+
IMAGE_NAME: "e_minguez/my-example-app"
12+
IMAGE_TAG: "latest"
13+
REGISTRY_CONNECTION: "quayio-e_minguez"
14+
15+
steps:
16+
17+
- task: Cache@2
18+
inputs:
19+
key: |
20+
sysdig-cli-scanner-cache | "$(Agent.OS)" | "$(CACHE_FOLDER)/sysdig-cli-scanner" | "$(CACHE_FOLDER)/latest_version.txt" | "$(CACHE_FOLDER)/db/main.db.meta.json" | "$(CACHE_FOLDER)/scanner-cache/inlineScannerCache.db"
21+
restoreKeys: |
22+
sysdig-cli-scanner-cache | "$(Agent.OS)"
23+
sysdig-cli-scanner-cache
24+
path: $(CACHE_FOLDER)
25+
displayName: Cache sysdig-cli-scanner and databases
26+
27+
- task: Cache@2
28+
displayName: Docker cache
29+
inputs:
30+
key: 'docker | "$(Agent.OS)" | cache'
31+
path: $(Pipeline.Workspace)/docker
32+
cacheHitVar: CACHE_RESTORED
33+
34+
- script: |
35+
docker load -i $(Pipeline.Workspace)/docker/cache.tar
36+
displayName: Docker restore
37+
condition: and(not(canceled()), eq(variables.CACHE_RESTORED, 'true'))
38+
39+
- task: Docker@2
40+
inputs:
41+
command: 'build'
42+
Dockerfile: 'love/Containerfile'
43+
buildContext: 'love/'
44+
repository: $(REGISTRY_HOST)/$(IMAGE_NAME)
45+
tags: $(IMAGE_TAG)
46+
addPipelineData: false
47+
addBaseImageData: false
48+
49+
- script: |
50+
curl -sLO https://download.sysdig.com/scanning/sysdig-cli-scanner/latest_version.txt
51+
mkdir -p $(CACHE_FOLDER)/db/
52+
if [ ! -f $(CACHE_FOLDER)/latest_version.txt ] || [ $(cat ./latest_version.txt) != $(cat $(CACHE_FOLDER)/latest_version.txt) ]; then
53+
cp ./latest_version.txt $(CACHE_FOLDER)/latest_version.txt
54+
curl -sL -o $(CACHE_FOLDER)/sysdig-cli-scanner "https://download.sysdig.com/scanning/bin/sysdig-cli-scanner/$(cat $(CACHE_FOLDER)/latest_version.txt)/linux/amd64/sysdig-cli-scanner"
55+
chmod +x $(CACHE_FOLDER)/sysdig-cli-scanner
56+
else
57+
echo "sysdig-cli-scanner latest version already downloaded"
58+
fi
59+
displayName: Download the sysdig-cli-scanner if needed
60+
61+
- script: |
62+
$(CACHE_FOLDER)/sysdig-cli-scanner \
63+
--apiurl $(SYSDIG_SECURE_ENDPOINT) \
64+
--console-log \
65+
--dbpath=$(CACHE_FOLDER)/db/ \
66+
--cachepath=$(CACHE_FOLDER)/scanner-cache/ \
67+
docker://$(REGISTRY_HOST)/$(IMAGE_NAME):$(IMAGE_TAG) \
68+
displayName: Run the sysdig-cli-scanner
69+
env:
70+
SECURE_API_TOKEN: $(TOKEN)
71+
72+
- task: Docker@2
73+
displayName: Push the container image
74+
inputs:
75+
containerRegistry: $(REGISTRY_CONNECTION)
76+
repository: $(IMAGE_NAME)
77+
command: push
78+
tags: $(IMAGE_TAG)
79+
addPipelineData: false
80+
addBaseImageData: false
81+
82+
- script: |
83+
mkdir -p $(Pipeline.Workspace)/docker
84+
docker save $(docker images -q) -o $(Pipeline.Workspace)/docker/cache.tar
85+
displayName: Docker save
86+
condition: and(not(canceled()), or(failed(), ne(variables.CACHE_RESTORED, 'true')))
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
FROM golang:1.18-alpine as builder
2+
WORKDIR /app
3+
COPY . .
4+
RUN go mod download
5+
RUN go build -o /love
6+
7+
FROM alpine
8+
COPY --from=builder /love /love
9+
EXPOSE 8080
10+
ENTRYPOINT [ "/love" ]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module love
2+
3+
go 1.18
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/http"
7+
)
8+
9+
func handler(w http.ResponseWriter, r *http.Request) {
10+
fmt.Fprintf(w, "I love %s!\n", r.URL.Path[1:])
11+
}
12+
13+
func main() {
14+
http.HandleFunc("/", handler)
15+
log.Fatal(http.ListenAndServe(":8080", nil))
16+
}

docs/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ The `no_proxy` variable can be used to define a list of hosts that don't use the
130130

131131
In this [repository](https://github.com/sysdiglabs/secure-inline-scan-examples/) you can find the following examples in alphabetical order:
132132

133+
* [AWS Codebuild](https://github.com/sysdiglabs/secure-inline-scan-examples/tree/main/new-scan-engine/aws-codebuild)
134+
* [Azure Pipelines (New scan engine)](https://github.com/sysdiglabs/secure-inline-scan-examples/tree/main/azure-pipelines)
133135
* [Google Cloud Build](https://github.com/sysdiglabs/secure-inline-scan-examples/tree/main/google-cloud-build)
134136
* [Jenkins](https://github.com/sysdiglabs/secure-inline-scan-examples/tree/main/jenkins)
135137
* [Scan from repository](https://github.com/sysdiglabs/secure-inline-scan-examples/tree/main/jenkins/jenkins-scan-from-repo)

0 commit comments

Comments
 (0)