Verständnis der Bestandsaufnahme für DevSecOps
In DevSecOps, dient Ihr Inventar als kritische, zentralisierte Liste aller Bausteine, aus denen Ihr Softwaresystem besteht. Es ist der zentrale Informationspunkt für alles, was Sie für die sichere Entwicklung, Bereitstellung und Verwaltung Ihrer Anwendungen in IBM Cloudbenötigen. Im Folgenden ist aufgeführt, was normalerweise in diesem Bestand enthalten ist:
-
Ressourcen fürIBM Cloud: Hierzu gehören virtuelle Server, serverunabhängige Funktionen, Cloudant-Datenbanken und alle anderen Services, die Sie in Ihrer IBM Cloud-Umgebung bereitgestellt haben.
-
Details zu Infrastructure as Code (IaC): Dazu gehören Terraform-Konfigurationen, Umgebungsvariablen, die in IBM® Cloud Foundry Artifactorygespeichert werden, sowie weitere Einstellungen, die festlegen, wie Ihre IBM Cloud-Ressourcen konfiguriert und geschützt werden.
-
Anwendungsabhängigkeiten: Dies sind Services, APIs und Mikroservices anderer Anbieter, auf die Ihre Cloudanwendungen angewiesen sind, um fehlerfrei zu funktionieren.
-
IBM® Key Protect for IBM Cloud® Geheime Schlüssel: Diese Angabe bezieht sich auf sensible Informationen, die für den Systembetrieb wichtig sind, wie Kennwörter, API-Schlüssel und Verschlüsselungsschlüssel. Diese erfordern eine sorgfältige Kontrolle und eine sichere Speicherung in IBM Key Protect.
Struktur und Inhalt eines Bestands
Das Bestandsmodell verfolgt die folgenden Elemente des Artefakts:
- Name des Artefakts
- Umgebung oder Region, in der sie bereitgestellt wird.
- Buildposition eines Artefakts (Pipelineausführung, Commit sha)
- Signatur des erstellten Artefakts
Verfolgen Sie Angaben während Artefaktbuilds und -bereitstellungen. Dies hilft auch bei Change Management-und Compliance-Audits.
Verzweigungen
Der Bestand ist in einem Git-Repository (repo) implementiert. Git ist bei der Verfolgung und Prüfung von Änderungen autark.
Verzweigungen werden als Umgebungen verwendet. Die Hauptverzweigung (master) wird von der Continuous Integration-Pipeline geschrieben und aktualisiert. Andere Umgebungen werden mittels Hochstufungen von der Hauptverzweigung aus
aktualisiert. Weitere Informationen zu Hochstufungen finden Sie im Abschnitt Hochstufung.
Bestandsinhalt
Der Bestand enthält für jedes Artefakt, das an der Bereitstellung beteiligt ist, einen Bestandseintrag. Ein Bestandseintrag verweist auf ein einziges Artefakt. Bestandseinträge sind JSON-Dateien, die in Ordnern strukturiert werden können und mit dem Eintragsnamen benannt sind.
Bestandsordner sind Teil des Eintragsnamens.
Beispiel
Wählen Sie einen Namen aus der folgenden Liste mit Eintragsnamen als Servicenamen:
- auth/service
- auth/db
- ui/service
- main_service
- helm-charts/main_service
Der Inhalt wird im Bestand mit der folgenden Struktur implementiert:
/
├── auth
│ ├── service
│ └── db
├── ui
│ └── service
├── helm-charts
│ └── main_service
└ main_service
Bestandseintragsformat
Der Typ Entry stellt das Schema des Bestandseintrags zwar mithilfe von Typescript-Syntax dar, kann jedoch konvertiert werden, damit Sie ein JSON-Schema verwenden können.
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;
}
Beispiel
Bestandseintrag für den Bildtyp des Assets
{
"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
}
Bestandseintrag für den Nicht-Image-Assettyp, z. B. Bereitstellung, Helm-Diagramme
{
"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
}
Verwenden Sie den Befehl cacao inventory add, um in den Bestand zu schreiben.
Bestandsworkflow
Der Bestand enthält neben der Verzweigung master mehrere Verzweigungen. Diese Verzweigungen können Bereitstellungsphasen, Umgebungen oder Regionen oder eine Kombination aus beidem darstellen. Die Struktur dieser Verzweigungen ist
von der Konfiguration und der Verwendung abhängig.
CI-Schreibvorgänge im Bestand
Die Verzweigung master wird aus Continuous Integration-Builds gefüllt. Die letzte Festschreibung im Ziel (in diesem Fall namens staging) enthält einen Tag, der deutlich macht, dass es sich um die letzte abgeschlossene
Bereitstellung handelt.
Wenn die Standardverzweigung für den Bestand auf eine andere Verzweigung umgeschaltet wird, müssen Sie die Commits aus der vorherigen Standardverzweigung in die neue Standardverzweigung umstellen, damit das Git-Commitprotokoll linear wird.
Sie können das Schreiben in den Bestand überspringen, indem Sie das Release-Script anpassen. Weitere Informationen finden Sie unter Release to inventory.
Umstufung
Eine Pull-Anforderung wird erstellt, wenn eine Hochstufung auf eine Zielverzweigung erfolgt. Der Inhalt der Pull-Anforderung füllt die Felder für Änderungsanforderungen. Nachdem die Pull-Anforderung geprüft wurde, können Sie sie zusammenführen.
Delta und Bereitstellung
Nach dem Zusammenführen der Pull-Anforderung für die Hochstufung kann die Bereitstellungsspipeline gestartet werden. Das Bereitstellungsdelta ist der Unterschied zwischen dem Inhalt der letzten abgeschlossenen Bereitstellung und der aktuellen Bereitstellung. Im Bereitstellungsdelta sind die Bestandselemente aufgelistet, die bereitgestellt werden.
Bestandszusammenfassung
Nachdem die Bereitstellung fertiggestellt worden ist, können Sie den Tag latest nach vorne verschieben.
Während des Auslösers im Einheitenmodus werden die Tags nicht erweitert. Der Zweck des Auslösers im Entwicklungsmodus ist nur zum Testen der CD-Pipeline.
Auf andere Umgebungen umstufen
Sie können Elemente von jeder Verzweigung auf eine andere hochstufen und bereitstellen.
Bestandslandschaft
Der aktuelle bereitgestellte Status enthält den Inhalt für die Bereitstellung in einer Umgebung. Jede beförderte Übergabe im Zielzweig enthält die entsprechende Pipeline-Lauf-ID und die Änderungsanforderungs-ID als Tag. Einige Festschreibungen können mehrere Tags aufweisen, wenn Sie beispielsweise eine fehlgeschlagene Bereitstellung wiederholen oder eine erneute Bereitstellung durchführen. Der Bestand enthält alle Informationen, die für die Wiederholung der Bereitstellungen erforderlich sind.
Konfiguration für ein einzelnes Ziel mit mehreren Regionen
Es werden mehrere latest Tags für eine einzige Zielumgebung eingeführt, so dass mehrere kontinuierliche Bereitstellungspipelines für unterschiedliche Anwendungsfälle auf demselben Ziel arbeiten können. Sie können beispielsweise
dieselbe Zielumgebung (z. B. us-south oder eu-de) für mehrere Regionen in der Produktionszielumgebung und der Bestandsverzweigung verwenden.
Sie müssen nicht für jede Region einen anderen Zweig einrichten, indem Sie die Eigenschaft region verwenden, z. B. us-south-prod und eu-de-prod, und die Aktion redundant durchführen. Stattdessen geben
Sie diese zusätzlichen Ziele für dieselbe Bestandsverzweigung an und verwenden Sie dann als Git-Tags.
In dieser Konfiguration hat der prod-Zweig mehrere latest-Tags auf demselben Zweig, wie us-south_prod_latest und eu-de_prod_latest. Jede Continuous-Deployment-Pipeline, die für die einzelnen Regionen
zuständig ist, kann diese Tags für die Bereitstellung verwenden.
Eine Reihe von Änderungen, die Sie überall bereitstellen möchten, könnte beispielsweise zunächst in einer einzigen Region freigegeben werden und dann schrittweise in anderen Regionen bereitgestellt werden, indem kontinuierliche Bereitstellungspipelines für diese Regionen verwendet werden.
Operationen für Bestand
Der Bestand enthält einige Basisoperationen, die über die Befehlszeilenschnittstelle (CLI) oder rein über Git und die GitHub-Befehlszeilenschnittstelle ausgeführt werden.
Befehle der Befehlszeilenschnittstelle
-
Erstellen Sie eine Pull-Anforderung für die Hochstufung von der Master- auf die Zielverzweigung im Staging.
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") -
Schließen Sie eine Bereitstellung ab, indem Sie den Tag
target_latestzu derselben Festschreibung wie den Tagpipeline-run-idverschieben.cocoa inventory label move \ --to-label="${PIPELINE_RUN_ID}" \ "target_latest"
Git und GitHub-CLI
-
Erstellen Sie eine Pull-Anforderung für die Hochstufung von der Master- auf die Zielverzweigung im Staging.
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 -
Schließen Sie eine Bereitstellung ab, indem Sie den Tag
target-latestzu derselben Festschreibung wie den Tagpipeline-run-idverschieben.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 -
Setzen Sie das Staging mit Git und der GitHub-Befehlszeilenschnittstelle auf einen früheren Zustand zurück.
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
Gängige Anwendungsfälle für die Arbeit mit Git-Repositorys
Weitere Informationen zum Arbeiten mit Git-Repositorys bieten die folgenden Beispielszenarios:
Dateien und Verzeichnisse im Inventar ausschließen
1-Pipeline schließt standardmäßig verdeckte Dateien und .md-Dateien im Bestand aus. Erstellen Sie eine Datei mit dem Namen .inventoryignore in Ihrem Bestandsrepository, um alle Dateien oder Verzeichnisse auszuschließen.
Die Pipeline sucht im Stammverzeichnis des Repositorys nach der Datei .inventoryignore.
Wenn Sie jedoch einen anderen Namen für die Bestandsausschlußdatei bevorzugen, können Sie ihn angeben, indem Sie den Schlüssel inventory-ignore-file als Umgebungseigenschaft in Ihrer Pipeline festlegen. Stellen Sie sicher, dass
sich diese Datei im Stammverzeichnis des Bestandsrepositorys befindet.
Wenn Ihre Datei beispielsweise den Namen .custominventoryignore hat, fügen Sie eine Umgebungsvariable inventory-ignore-file mit dem Wert custominventoryignore hinzu.
Im Folgenden finden Sie ein Beispiel für den Inhalt der Datei .custominventoryignore in zwei Formaten:
.md
sample_file
sample_directory/
# Ignore everything
**
# But keep these artifacts
!sample_directory/
!sample_file
Im Folgenden wird der Zweck der Einträge in der Beispieldatei .custominventoryignore erläutert:
.md: Schließt alle Dateien mit der Erweiterung.mdaus. Fügen Sie nicht*am Anfang ein, wie*.md, da Regex nicht unterstützt wird.sample_file: Schließt eine bestimmte Datei im gesamten Repository aus.sample_directory/: Schließt das gesamte Verzeichnis aus. Vermeiden Sie das Hinzufügen von*am Ende, verwenden Siesample_directory/*, da Regex nicht unterstützt wird.- Wenn eine Datei keine Einträge enthält oder eine leere Zeile, werden alle Dateien ausgeschlossen. Bitte lassen Sie keine leeren Einträge oder Zeilen in der Inventar-Ignore-Datei.
**: Ignoriert alles im Repository.!sample_directory/und!sample_file: Hebt die Ignorierregel auf, so dass diese spezifischen Dateien oder Verzeichnisse auch dann erhalten bleiben, wenn**vorhanden ist.