Comprendre l'inventaire pour DevSecOps
Dans DevSecOps, votre inventaire sert de liste centralisée critique de tous les éléments constitutifs de votre système logiciel. Il devient le point d'information unique de tout ce dont vous avez besoin pour développer, déployer et gérer vos applications en toute sécurité sur IBM Cloud. Voici ce qui est généralement inclus dans cet inventaire:
-
RessourcesIBM Cloud: inclut les serveurs virtuels, les fonctions sans serveur, les bases de données Cloudant et tous les autres services que vous avez mis à disposition dans votre environnement IBM Cloud.
-
Détails de l'infrastructure sous forme de code (IaC): cela inclut les configurations Terraform, les variables d'environnement stockées dans IBM® Cloud Foundry Artifactory, ainsi que d'autres paramètres qui déterminent la manière dont vos ressources IBM Cloud sont configurées et sécurisées.
-
Dépendances d'application: il s'agit de services, d'API et de microservices tiers sur lesquels vos applications cloud s'appuient pour fonctionner parfaitement.
-
IBM® Key Protect for IBM Cloud®: informations sensibles essentielles au fonctionnement du système, telles que les mots de passe, les clés d'API et les clés de chiffrement. Elles nécessitent un contrôle méticuleux et un stockage sécurisé dans IBM Key Protect.
Structure et contenu d'un inventaire
Le modèle d'inventaire suit les éléments suivants de l'artefact:
- Nom de l'artefact
- Environnement ou région dans lequel il sera déployé.
- Emplacement de génération d'un artefact (exécution de pipeline, validation sha)
- Signature de l'artefact généré
Suivez les informations collectées lors des générations et des déploiements d'artefact. Cela permet également d'effectuer des audits de gestion des changements et de conformité.
Branches
L'inventaire est implémenté en tant que référentiel Git. Git est auto-suffisant dans le suivi et l'audit des modifications.
Les branches sont utilisées comme environnements. La branche principale (master) est écrite et mise à jour par le pipeline d'intégration continue. Les autres environnements sont mis à jour à partir de la branche principale à l'aide
de promotions. Pour plus d'informations sur les promotions, voir la section Promotion.
Contenu d'inventaire
L'inventaire contient une entrée d'inventaire pour chaque artefact qui participe au déploiement. Une entrée d'inventaire pointe vers un artefact. Les entrées d'inventaire sont des fichiers JSON qui peuvent être structurés dans des dossiers et qui sont nommés à l'aide du nom d'entrée.
Les dossiers d'inventaire font partie du nom d'entrée.
Exemple
Choisissez un nom dans la liste suivante de noms d'entrée comme nom de service:
- auth/service
- auth/db
- ui/service
- main_service
- helm-charts/main_service
Le contenu est implémenté dans l'inventaire à l'aide de la structure suivante :
/
├── auth
│ ├── service
│ └── db
├── ui
│ └── service
├── helm-charts
│ └── main_service
└ main_service
Format d'entrée d'inventaire
Bien que le type Entry représente le schéma de l'entrée d'inventaire avec la syntaxe typescript, vous pouvez convertir le schéma pour utiliser un schéma 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;
}
Exemple
Entrée de stock pour le type d'image de l'actif
{
"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
}
Entrée d'inventaire pour le type d'actif autre que l'image, tel que le déploiement, les chartes Helm
{
"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
}
Utilisez la commande cacao inventory add pour écrire dans l'inventaire.
Flux de travaux d'inventaire
L'inventaire contient plusieurs branches en plus de la branche master. Ces branches peuvent représenter des étapes, des environnements ou des régions de déploiement ou un mélange de ces options. La structure de ces branches dépend
de la configuration et de l'utilisation.
L'intégration continue écrit dans l'inventaire
La branche master est renseignée à partir des générations d'intégration continue. La dernière validation dans la cible (en l'occurrence, staging) contient une étiquette indiquant qu'il s'agit du dernier déploiement
effectué.
Si la branche par défaut de l'inventaire est basculée vers une autre branche, vous devez resynchroniser les validations de la branche par défaut précédente dans la nouvelle branche par défaut pour rendre l'historique des validations Git linéaire.
Vous pouvez ignorer l'écriture dans l'inventaire en personnalisant le script d'édition. Pour plus d'informations, voir Mise en stock.
Promotion
Une demande d'extraction est créée lorsque vous effectuez la promotion vers une branche cible. Le contenu de la demande d'extraction remplit les zones de demande de changement. Une fois la demande d'extraction révisée, vous pouvez la fusionner.
Ecart de déploiement
Une fois la demande d'extraction de promotion fusionnée, le pipeline de déploiement peut démarrer. L'écart de déploiement est la différence entre le contenu du dernier déploiement effectué et celui du déploiement en cours. L'écart de déploiement répertorie les éléments d'inventaire en cours de déploiement.
Conclusion de l'inventaire
Une fois le déploiement terminé, vous pouvez déplacer l'étiquette latest plus loin.
Lors du déclenchement du mode de développement, les balises ne seront pas avancées. L'objectif du déclencheur de mode de développement est uniquement de tester le pipeline CD uniquement.
Promotion vers d'autres environnements
Vous pouvez effectuer une promotion et un déploiement à partir de n'importe quelle branche vers une autre branche.
Paysage d'inventaire
L'état actuellement déployé contient le contenu à déployer dans un environnement. Chaque commit promu dans la branche cible contient l'ID de l'exécution du pipeline et l'ID de la demande de changement en tant qu'étiquette. Certaines validations peuvent comporter plusieurs étiquettes, par exemple, lorsque vous relancez un déploiement ayant échoué ou que vous effectuez un nouveau déploiement. L'inventaire contient tous les éléments d'information nécessaires pour réexécuter les déploiements.
Configuration pour une cible avec plusieurs régions
Plusieurs tags latest sont introduits pour un seul environnement cible afin que plusieurs pipelines de déploiement continu puissent fonctionner sur la même cible, pour différents types de cas d'utilisation. Vous pouvez utiliser,
par exemple, le même environnement cible (par exemple, us-south ou eu-de) pour plusieurs régions dans l'environnement cible de production et la branche d'inventaire.
Il n'est pas nécessaire de créer une branche différente pour chaque région en utilisant la propriété region, telle que us-south-prod et eu-de-prod, et d'exécuter la promotion de manière redondante. A
la place, indiquez ces cibles supplémentaires pour la même branche d'inventaire, puis utilisez-les en tant qu'étiquettes Git.
Dans cette configuration, la branche prod possède plusieurs étiquettes latest sur la même branche, telles que us-south_prod_latest et eu-de_prod_latest. Chaque pipeline de déploiement continu responsable
de chaque région peut utiliser ces balises pour le déploiement.
Par exemple, un ensemble de changements que vous prévoyez de déployer partout peut être publié dans une seule région d'abord, puis déployé progressivement dans d'autres régions en utilisant des pipelines de déploiement continu pour cibler ces régions.
Opérations d'inventaire
L'inventaire contient des informations de base qui s'exécutent à l'aide de l'interface de ligne de commande, de pure Git et de l'interface de ligne de commande GitHub.
Commandes de l'interface de ligne de commande
-
Créez une demande d'extraction de promotion à partir de la branche principale vers la branche cible dans un environnement de préproduction.
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") -
Terminez un déploiement en déplaçant l'étiquette
target_latestvers la même validation que l'étiquettepipeline-run-id.cocoa inventory label move \ --to-label="${PIPELINE_RUN_ID}" \ "target_latest"
Interface de ligne de commande Git et GitHub
-
Créez une demande d'extraction de promotion à partir de la branche principale vers la branche cible dans un environnement de préproduction.
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 -
Terminez un déploiement en déplaçant l'étiquette
target-latestvers la même validation que l'étiquettepipeline-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 -
Rétablissez un état antérieur de l'environnement de préproduction à l'aide de Git et de l'interface de ligne de commande 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
Cas d'utilisation courants pour utiliser des référentiels Git
Pour plus d'informations sur l'utilisation de référentiels Git, voir les exemples de scénario suivants :
Comment exclure des fichiers et des répertoires dans l'inventaire
One-Pipeline exclut par défaut les fichiers masqués et les fichiers .md de l'inventaire. Créez un fichier nommé .inventoryignore dans votre référentiel d'inventaire pour exclure tous les fichiers ou répertoires. Le
pipeline recherche le fichier .inventoryignore à la racine du référentiel.
Toutefois, si vous préférez un nom différent pour le fichier d'exclusion d'inventaire, vous pouvez le spécifier en définissant la clé inventory-ignore-file comme propriété d'environnement dans votre pipeline. Assurez-vous que ce
fichier se trouve à la racine du référentiel d'inventaire.
Par exemple, si votre fichier est nommé .custominventoryignore, ajoutez une variable d'environnement inventory-ignore-file avec la valeur custominventoryignore.
Voici un exemple de contenu du fichier .custominventoryignore dans deux formats :
.md
sample_file
sample_directory/
# Ignore everything
**
# But keep these artifacts
!sample_directory/
!sample_file
Les paragraphes suivants expliquent l'objectif des entrées du fichier de l'exemple .custominventoryignore:
.md: exclut tous les fichiers portant l'extension.md. N'ajoutez pas*au début, comme*.md, car les expressions rationnelles ne sont pas prises en charge.sample_file: Exclut le fichier spécifique dans l'ensemble du référentiel.sample_directory/: Exclut le répertoire entier. Évitez d'ajouter*à la fin, utilisezsample_directory/*, car les expressions rationnelles ne sont pas prises en charge.- Si un fichier ne contient aucune entrée ou une ligne vide, tous les fichiers seront exclus. Veuillez ne pas laisser d'entrées ou de lignes vides dans le fichier d'inventaire.
**: Ignore tout ce qui se trouve dans le référentiel.!sample_directory/et!sample_file: annule la règle d'ignorance, en conservant ces fichiers ou répertoires spécifiques même si**est présent.