Comprensione dell'inventario per DevSecOps
In DevSecOps, l'inventario funge da elenco critico centralizzato di tutti gli elementi che compongono il sistema software. Diventa l'unico punto di informazione di cui hai bisogno per sviluppare, distribuire e gestire le tue applicazioni in modo sicuro su IBM Cloud. Ecco cosa viene incluso in questo inventario:
-
IBM Cloud risorse: include i server virtuali, le funzioni senza server, i database Cloudant e tutti gli altri servizi di cui hai eseguito il provisioning nel tuo ambiente IBM Cloud.
-
Dettagli dell'infrastruttura come codice (IaC): questo include le configurazioni Terraform, le variabili di ambiente memorizzate in IBM® Cloud Foundry Artifactorye altre impostazioni che indicano come le tue risorse IBM Cloud sono configurate e protette.
-
Dipendenze applicazione: si tratta di servizi di terzi, API e microservizi su cui si basano le tue applicazioni cloud per funzionare in modo impeccabile.
-
IBM® Key Protect for IBM Cloud® Segreti: si riferisce alle informazioni sensibili essenziali per il funzionamento del sistema, come password, chiavi API e chiavi di crittografia. Questi richiedono un controllo meticoloso e un'archiviazione protetta in IBM Key Protect.
Struttura e contenuto di un inventario
Il modello di inventario tiene traccia dei seguenti elementi della risorsa utente:
- Nome della risorsa utente
- Ambiente o regione in cui verrà distribuito.
- Percorso build di una risorsa utente (esecuzione pipeline, commit sha)
- Firma della risorsa utente creata
Tenere traccia delle prove durante le build e le distribuzioni delle risorse utente. Ciò aiuta anche con la gestione delle modifiche e i controlli di conformità.
Rami
L'inventario è implementato in un repository (repo) Git. Git è autosufficiente nella traccia e nel controllo delle modifiche.
I rami vengono utilizzati come ambienti. Il ramo principale (master) viene scritto e aggiornato dalla pipeline di integrazione continua. Altri ambienti vengono aggiornati dal ramo principale utilizzando le promozioni. Per ulteriori
informazioni sulle promozioni, consultare la sezione Promozione.
Contenuto inventario
L'inventario contiene una voce di inventario per ogni risorsa utente che partecipa alla distribuzione. Una voce di inventario punta a una singola risorsa utente. Le voci di inventario sono file JSON che è possibile strutturare in cartelle e che vengono denominati utilizzando il nome della voce.
Le cartelle di inventario fanno parte del nome della voce.
Esempio
Scegliere un nome dal seguente elenco di nomi di voci come nome servizio:
- aut/servizio
- aut/db
- ui/servizio
- servizio principale
- helm - charts/main_service
Il contenuto viene implementato nell'inventario utilizzando la seguente struttura:
/
├── auth
│ ├── service
│ └── db
├── ui
│ └── service
├── helm-charts
│ └── main_service
└ main_service
Formato voce inventario
Sebbene il tipo Entry rappresenti lo schema della voce di inventario utilizzando la sintassi typescript, è possibile convertirlo in uno schema JSON.
interface Entry {
repository_url: string;
artifact: string;
build_number: number;
commit_sha: string;
name: string;
pipeline_run_id: string;
version: string;
app_artifacts: {
signature: string;
provenance: string;
[key: string]: any;
}
type: string;
sha256: string;
provenance: string;
signature: string;
}
Esempio
Voce di inventario per il tipo di immagine dell'asset
{
"repository_url": "https://github.com/test-org/compliance-app-20201211", # source code repository url of the image artifact
"artifact": "us.icr.io/namespace/hello-compliance-app:20201217081811-master-b85e3d472e9cc35b429c39e8c3f9eb282738c20a@sha256:da36831d5154307ac9ca4b8d900df2da0c6c14754977c32479dc62994b5722d0", # image artifact name, should be in a format like <static_name>:<version>@sha256:<sha256> OR <static_name>@sha256:<sha256>
"build_number": 21, # pipeline build number
"commit_sha": "b85e3d472e9cc35b429c39e8c3f9eb282738c20a", # should be a proper git commit sha
"name": "hello-compliance-app", # name of the inventory entry file name
"pipeline_run_id": "f21321bf-9054-4bf3-80a8-4fb34743b7d9", # pipeline run id where artifact was built
"version": "v1", # version of the artifact
"app_artifacts": {}, # any additional information can be stored here
"type": "image",
"sha256": "sha256:da36831d5154307ac9ca4b8d900df2da0c6c14754977c32479dc62994b5722d0",
"provenance": "us.icr.io/namespace/hello-compliance-app:20201217081811-master-b85e3d472e9cc35b429c39e8c3f9eb282738c20a@sha256:da36831d5154307ac9ca4b8d900df2da0c6c14754977c32479dc62994b5722d0", # The fully qualified URL where artifact is stored, in case of image artifact, it is same as the artifact field
"signature": "owFNUX1IE3EY3vwAEy0VyoSJdkVWtu0+d3eTjNIIi0jETCSU3353cz+83V23myi2BlFgYiUFqSmZLciUzCJkRYJp9IEWFWXB0hAyrBQxEjIIuhFSf70vL8/7vM/zPi3JsaYEc+TnbqG8qrnTPDZ8w2WqiqwtacCghnQEgYQ5GzAkiLKO9PpoLyiwRtSsmugWNVGGIubE/D4bgpoNKXag60gCdo8oSYoVKl5VQsDAWIGqOkmcxAmSYHGO4AjC6gU+3eBxcYxICTRLijyEFOOiSR5SvMhBys2LLpIjWYqDJA6wwHYMeUG1+J8GL5CRW/TpVgFVG8VQ4vMAknE4BUA5OIoQGIKhKZwFkIeAdnECj+OCmxQADh2QoFmG5lkWUiTN8gJ0kDxPuxiWJAU8ekyvV6PegK54EcyGiqwDJItatg9Vy0D3a2IUpKg6UuS/T4KaaIC1fzuMDbfhmMGEvIY64FUxJ+Ew3PMU5SADgdNmKs5kTjBlrtsQ99iyY49nns8o6jsXWgkjPiYahClxVcrK5Flngumz2j7YdmD0ecutytsvxxNPHflKlRV2RyqD69NjC6Smji9XuukFyZ+lvM18gUr7F4NXge9YyZPik411tc1n9bKO/hDz7oGaX/ur94OnNHiwOG6n5ZsrsCsvtyvmkH4zOWlrRWuL7fzgj9zlcCTAhtu2LbeGLNfv3Ju0Jc9PZPk7Pm3Ov2CW+2xj8ReX6ooGamZ610yqRM/+8Qo2XnOeyZzbVKgs+f2+9unpJOve4Tmla+PdqftDWkHPm9Vq3nsyZ2DUkmP/nTb7qNw5l2SfWtiSemJx9nLaYOpx6amlOT18aeIwJQhHg1XOjJF9r18NXQvPuL9rH5tSQqbGhyN/AA==" # The signature of the artifact
}
Voce di inventario per il tipo di asset non immagine, come i grafici helm e di distribuzione
{
"repository_url": "https://github.com/test-org/compliance-app-20201211", # source code repository url of the artifact
"artifact": "deployment.yaml", # artifact name, must be contant every build
"build_number": 21, # pipeline build number
"commit_sha": "b85e3d472e9cc35b429c39e8c3f9eb282738c20a", # must be a proper git commit sha
"name": "hello-compliance-app-deployment", # name of the inventory entry file name
"pipeline_run_id": "f21321bf-9054-4bf3-80a8-4fb34743b7d9", # pipeline run id where artifact was built
"version": "v1", # version of the artifact
"app_artifacts": {}, # any additional information can be stored here
"type": "deployment", # type of the artifact
"sha256": "sha256:da36831d5154307ac9ca4b8d900df2da0c6c14754977c32479dc62994b5722d0", # sha256 of the artifact
"provenance": "https://raw.github.ibm.com/org/my-app/commit-1/deployment.yaml", # The fully qualified URL where artifact is stored
"signature": "owFNUX1IE3EY3vwAEy0VyoSJdkVWtu0+d3eTjNIIi0jETCSU3353cz+83V23myi2BlFgYiUFqSmZLciUzCJkRYJp9IEWFWXB0hAyrBQxEjIIuhFSf70vL8/7vM/zPi3JsaYEc+TnbqG8qrnTPDZ8w2WqiqwtacCghnQEgYQ5GzAkiLKO9PpoLyiwRtSsmugWNVGGIubE/D4bgpoNKXag60gCdo8oSYoVKl5VQsDAWIGqOkmcxAmSYHGO4AjC6gU+3eBxcYxICTRLijyEFOOiSR5SvMhBys2LLpIjWYqDJA6wwHYMeUG1+J8GL5CRW/TpVgFVG8VQ4vMAknE4BUA5OIoQGIKhKZwFkIeAdnECj+OCmxQADh2QoFmG5lkWUiTN8gJ0kDxPuxiWJAU8ekyvV6PegK54EcyGiqwDJItatg9Vy0D3a2IUpKg6UuS/T4KaaIC1fzuMDbfhmMGEvIY64FUxJ+Ew3PMU5SADgdNmKs5kTjBlrtsQ99iyY49nns8o6jsXWgkjPiYahClxVcrK5Flngumz2j7YdmD0ecutytsvxxNPHflKlRV2RyqD69NjC6Smji9XuukFyZ+lvM18gUr7F4NXge9YyZPik411tc1n9bKO/hDz7oGaX/ur94OnNHiwOG6n5ZsrsCsvtyvmkH4zOWlrRWuL7fzgj9zlcCTAhtu2LbeGLNfv3Ju0Jc9PZPk7Pm3Ov2CW+2xj8ReX6ooGamZ610yqRM/+8Qo2XnOeyZzbVKgs+f2+9unpJOve4Tmla+PdqftDWkHPm9Vq3nsyZ2DUkmP/nTb7qNw5l2SfWtiSemJx9nLaYOpx6amlOT18aeIwJQhHg1XOjJF9r18NXQvPuL9rH5tSQqbGhyN/AA==" # The signature of the artifact
}
Utilizzare il comando cacao inventory add per scrivere nell'inventario.
Flusso di lavoro inventario
L'inventario contiene diversi rami diversi dal ramo master. Questi rami possono rappresentare fasi di distribuzione, ambienti o regioni o una combinazione di entrambi. La struttura di questi rami dipende dalla configurazione e dall'utilizzo.
Scritture CI nell'inventario
Il ramo master è popolato da build di integrazione continua. L'ultimo commit nella destinazione (in questo caso denominato staging) contiene una tag che mostra che si è trattato dell'ultima distribuzione conclusa.
Se il ramo predefinito per l'inventario è commutato in un altro ramo, è necessario modificare i commit dal ramo predefinito precedente nel nuovo ramo predefinito per rendere lineare la cronologia di commit Git.
È possibile saltare la scrittura nell'inventario personalizzando lo script di rilascio. Per ulteriori informazioni, consultare Release to inventory.
Promozione
Una richiesta di pull viene creata quando si verifica la promozione a un ramo di destinazione. Il contenuto della richiesta di pull popola i campi della richiesta di modifica. Una volta revisionata la richiesta di pull, è possibile unirla.
Delta e distribuzione
Una volta unita la richiesta di pull della promozione, è possibile avviare la pipeline di distribuzione. Il delta di distribuzione è la differenza tra il contenuto dell'ultima distribuzione conclusa e la distribuzione corrente. Il delta di distribuzione elenca gli elementi dell'inventario che vengono distribuiti.
Conclusione inventario
Al termine della distribuzione, è possibile spostare la tag latest in avanti.
Durante il trigger della modalità di sviluppo, i tag non saranno avanzati. Lo scopo del trigger della modalità di sviluppo è solo per testare la pipeline CD.
Promuovi ad altri ambienti
È possibile promuovere e distribuire da qualsiasi ramo a un altro.
Gruppo di inventario
Lo stato distribuito corrente contiene il contenuto da distribuire a un ambiente. Ogni commit promosso nel ramo di destinazione contiene l'ID di esecuzione della pipeline pertinente e l'ID richiesta di modifica come tag. Alcuni commit possono avere più tag, ad esempio, quando si tenta nuovamente una distribuzione o una distribuzione non riuscita. L'inventario contiene tutte le informazioni per ripetere le distribuzioni.
Configurazione per una singola destinazione con più regioni
Sono state introdotte più tag latest per un singolo ambiente di destinazione in modo che più pipeline di distribuzione continua possano funzionare sulla stessa destinazione, per diversi tipi di casi di utilizzo. È possibile utilizzare,
ad esempio, lo stesso ambiente di destinazione (come us-south o eu-de) per più regioni nell'ambiente di destinazione della produzione e nel ramo di inventario.
Non è necessario configurare un ramo differente per ogni regione utilizzando la proprietà region, come us-south-prod e eu-de-prod, ed eseguire la promozione in modo ridondante. Specificare invece queste
destinazioni aggiuntive per lo stesso ramo di inventario e utilizzarle come tag Git.
In questa configurazione, il ramo prod ha più tag latest sullo stesso ramo, come us-south_prod_latest e eu-de_prod_latest. Ogni pipeline di distribuzione continua responsabile per ogni regione può utilizzare
tali tag per la distribuzione.
Ad esempio, una serie di modifiche che prevedi di distribuire ovunque potrebbe essere rilasciata prima in una singola regione e poi gradualmente distribuita ad altre regioni utilizzando le pipeline di distribuzione continua come destinazione per tali regioni.
Operazioni di inventario
L'inventario contiene alcune operazioni di base che vengono eseguite utilizzando la CLI o Git puro e la CLI GitHub.
Comandi della CLI
-
Creare una richiesta di pull della promozione dal master al ramo di destinazione in fase di preparazione.
cocoa inventory promote \ --source="master" \ --target="staging" \ --priority="moderate" \ --assigned-to="assignee@ibm.com" \ --description="Change description" \ --purpose="Change purpose" \ --impact="Change impact" \ --backout-plan="Details on backout and rollback") -
Concludere una distribuzione spostando la tag
target_latestnello stesso commit della tagpipeline-run-id.cocoa inventory label move \ --to-label="${PIPELINE_RUN_ID}" \ "target_latest"
Git e la CLI GitHub
-
Creare una richiesta di pull della promozione dal master al ramo di destinazione in fase di preparazione.
promote() { if [ -z $1 ] || [ -z $2 ]; then echo "Missing source and target" exit 1 fi local source="$1" local target="$2" if ! git show-ref "refs/remotes/origin/$target"; then # Create a new target branch, from the beginning of master git checkout master git checkout -b "$target" $(git rev-list --max-parents=0 HEAD) git_push fi git checkout "$source" git pull --rebase # Create a promotion branch for the PR # this can be discarded after the Promotion PR merge git checkout -b "promote-$source-to-$target" git push --set-upstream origin "promote-$source-to-$target" # Create PR from promotion branch to target branch gh pr create \ --base "$target" \ --head "promote-$source-to-$target" \ --title "Promote $source to $target" \ --body "" \ --repo "https://github.com/org/inventory-repository" # promotion branch can be deleted once the PR was merged } $ promote master staging -
Concludere una distribuzione spostando la tag
target-latestnello stesso commit della tagpipeline-run-id.conclude () { local target="$1" local tag="$2" latest="$1-latest" # remove the latest tag git push origin ":refs/tags/$latest" # find the commit hash of the target tag sha=$(git rev-list -n 1 $tag) # add the latest tag to the same commit of the target tag git tag -fa "$latest" -m "" $sha git push --tags --force } $ conclude staging pipeline-run-fe33b05c -
Ripristina la preparazione a uno stato precedente utilizzando Git e la CLI GitHub.
revert () { local branch="$1" local commit="$2" # create a revert branch from the target branch git checkout "$branch" git pull --rebase git checkout -b "$branch-revert" # revert commits since the target commit, then commit and push git revert -n $(git rev-list --no-merges HEAD...$commit) git commit -m "revert $branch to $commit" git push --set-upstream origin "$branch-revert" # create PR from revert branch to the target branch gh pr create \ --base "$branch" \ --head "$branch-revert" \ --title "Revert $branch to $commit" \ --body "" \ --repo "$REPO" # revert branch can be deleted once the PR was merged } $ revert staging ba3b8e5ed3320e6b4981077e1a1627f08de4f511
Casi di utilizzo comuni per l'utilizzo dei repository Git
Per ulteriori informazioni sull'utilizzo dei repository Git, vedi questi scenari di esempio:
Come escludere file e directory nell'inventario
Uno - Pipeline esclude i file nascosti e i file .md nell'inventario per default. Creare un file denominato .inventoryignore nel repository di inventario per escludere eventuali file o directory. La pipeline ricerca
il file .inventoryignore nella root del repository.
Tuttavia, se si preferisce un nome diverso per il file di esclusione dell'inventario, è possibile specificarlo impostando la chiave inventory-ignore-file come proprietà dell'ambiente nella pipeline. Assicurarsi che questo file si
trova nella root del repository di inventario.
Ad esempio, se il file è denominato .custominventoryignore, aggiungere una variabile di ambiente inventory-ignore-file con il valore custominventoryignore.
Di seguito è riportato un esempio di contenuto per il file .custominventoryignore in due formati:
.md
sample_file
sample_directory/
# Ignore everything
**
# But keep these artifacts
!sample_directory/
!sample_file
Di seguito viene spiegato lo scopo delle voci del file di esempio .custominventoryignore:
.md: Esclude tutti i file con estensione.md. Non aggiungere*all'inizio, come*.md, poiché la regex non è supportata.sample_file: Esclude il file specifico in tutto il repository.sample_directory/: Esclude l'intera directory. Evitare di aggiungere*alla fine, utilizzaresample_directory/*, poiché la regex non è supportata.- Se un file non contiene voci o una riga vuota, tutti i file vengono esclusi. Non lasciare voci o righe vuote nel file di ignoranza dell'inventario.
**: Ignora tutto ciò che è presente nel repository.!sample_directory/e!sample_file: nega la regola di ignoranza, mantenendo questi file o directory specifici anche se**è presente.