Blog | WeScale

Organiser vos paramètres applicatifs dans AWS

Rédigé par Akram BLOUZA | 10/12/2019

Organisation AWS


Afin d’assurer un cloisonnement maximal entre certaines plateformes et permettre une meilleure gestion des aspects sécurité et utilisateurs, il est recommandé de s’appuyer sur le service AWS Organizations permettant de créer une arborescence de comptes AWS.

Voici un exemple d’une partie d’une organisation AWS que vous pourriez retrouver dans vos projets :

Il s’agit d’une organisation permettant une meilleure gestion de vos environnements techniques dans un contexte AWS :

  • Meilleure maîtrise de la facturation AWS avec une consolidation par environnement technique au niveau du compte root.
  • Cloisonnement entre vos environnements techniques.
  • Meilleure sécurité en rattachant des “Service Control Policies” (SCP) aux unités d’organisations (OU).

Problématique



Reprenons l’exemple de l’organisation AWS présentée précédemment. Nous avons choisi trois environnements (donc accounts AWS) de non production et un seul environnement (donc un seul account AWS) de production, chacun rattaché à leur propre unité d’organisation (UO).

Au sein de cette organisation, un account AWS qui correspond à un environnement technique héberge tous les projets métiers. Chaque projet, ou même service d’un projet, possède ses propres paramètres applicatifs.

Il est donc essentiel d’implémenter un mécanisme normalisé permettant à une application de retrouver ses propres paramètres.

La solution apportée est l’utilisation d’une organisation par hiérarchie pour la gestion de vos paramètres avec AWS Systems Manager Parameter Store.


Une organisation par hiérarchie pour vos paramètres


AWS Systems Manager Parameter Store apporte une organisation par hiérarchie à vos paramètres applicatifs. Cette organisation permet à l’application de récupérer d’une manière simple et en utilisant l’API AWS les propriétés qui la concerne.

Prenons l’exemple d’une application bancaire composée de plusieurs micro-services. Chaque micro-service est un conteneur. Chaque micro-service cherche ses données métier chez un contributeur, donc source de données différente. Cette application possède deux micro-services : Personne Physique et Crédit. Chaque micro-service possède des propriétés stockées dans le Parameter Store d’AWS qui seront injectées en variables d’environnement au démarrage des conteneurs de ces micro-services.

Comment peut-on organiser les propriétés de ces deux micro-services ?

J’ai opté pour ce type d’organisation :


Voici quelques exemples de propriétés :


Versionner vos paramètres applicatifs


Comme vous l’avez constaté, les propriétés des applications ne sont pas rattachées aux livrables applicatifs. En l’état actuel, il est donc impossible de retrouver les valeurs des propriétés applicatives dans une version antérieure. Ceci pourrait être très problématique, surtout si on veut effectuer un retour en arrière vers une ancienne version.

Il est donc nécessaire d’ajouter une métadonnée à rattacher à chaque paramètre applicatif avec la version de l’application. Pour cela, j’utilise la fonctionnalité d’étiquetage (labels) d’AWS Systems Manager Parameter Store et je rajoute à la création de chaque paramètre applicatif l’étiquette version. Je reprends l’exemple précédent de l’application bancaire :



Protéger vos paramètres applicatifs


L’ensemble des paramètres de tous vos projets d’un environnement technique sont créés dans un seul endroit. Il est donc important d’effectuer un cloisonnement projet sur ces paramètres pour éviter qu’un administrateur d’un projet effectue des manipulations non autorisées sur des paramètres d’un autre projet, ou qu’une ressource AWS accède à des paramètres qui ne la concerne pas.

Ceci se fait par la création de stratégies IAM qui utilisent les balises (tags) pour restreindre la manipulation des paramètres.

Voici un exemple d’une stratégie IAM à rattacher à toutes les ressources du micro-service crédit. Ces ressources ne doivent manipuler que les paramètres qui ont une balise “service” ayant une valeur “credit”:


{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "ssm:*"
         ],
         "Resource":"*",
         "Condition":{
            "StringLike":{
               "ssm:resourceTag/service":[
                  “credit"
               ]
            }
         }
      }
   ]
}

Création et recherche de vos paramètres


Maintenant que vous avez compris comment organiser vos paramètres applicatifs dans AWS, nous devrons aller dans la pratique pour expliquer comment créer ces paramètres avec des métadonnées dans AWS et comment les retrouver facilement.


Création des paramètres dans AWS


Au moment de l’écriture de cet article, il n’existe aucun moyen pour ajouter un étiquetage à un parameter Store avec Terraform. Sur ce sujet, une issue Github a été créée pour faire voter l’intégration de l'étiquetage au niveau des paramètres store : https://github.com/terraform-providers/terraform-provider-aws/issues/9102.

Aujourd’hui, il est donc nécessaire d’utiliser l’API AWS pour manipuler des paramètres store.

 

  1. Création d’un paramètre store :

Le paramètre store à créer pourra avoir comme type : SecureString. Ce type permet de protéger les paramètres ayant des données sensibles en les stockant d’une manière sécurisée en utilisant une clé principale client KMS pour chiffrer la valeur du paramètre. Vous pouvez aussi utiliser le service AWS Secrets Manager qui est plus riche en fonctionnalités pour mieux gérer vos secrets applicatifs.

$ aws ssm put-parameter --name /ma-banque/pp/standard/db-name --type SecureString --value ”personnephysique” --overwrite 1> /dev/null
</code></pre>

La vérification de la création du paramètre utilisant la console AWS :

2. Associer un label avec la version correspondante de l’applicatif à la dernière version du paramètre. Ici je rajoute le label v1.0.0 :

$ aws ssm label-parameter-version --name /ma-banque/pp/standard/db-name --labels "v1.0.0"
{
    "ParameterVersion": 1, 
    "InvalidLabels": []
}

La vérification de l’association du label au paramètre utilisant la console AWS :

 

Je crée une deuxième version du paramètre "/ma-banque/pp/standard/db-name" et je l’associe à un label ayant la nouvelle version applicative v1.0.1 :

aws ssm put-parameter --name /ma-banque/pp/standard/db-name --type SecureString --value ”personnephysique2” --overwrite 1> /dev/null

aws ssm label-parameter-version --name /ma-banque/pp/standard/db-name --labels "v1.0.1"
{
    		"ParameterVersion": 2, 
    		"InvalidLabels": []
}

Pour lister tous les paramètres de tous vos applications :

aws ssm describe-parameters


{
    "Parameters": [
     {
            "KeyId": "alias/aws/ssm", 
            "Name": "/ma-banque/pp/standard/db-name", 
            "LastModifiedDate": 1575848507.452, 
            "Version": 2, 
            "LastModifiedUser": xxx ,
            "Policies": [], 
            "Tier": "Standard", 
            "Type": "SecureString"
        }

    ]
}

Pour afficher la valeur de la dernière version de la propriété "/ma-banque/pp/standard/" :

aws ssm get-parameter --with-decryption --name /ma-banque/pp/standard/db-name

{
    "Parameter": {
        "Name": "/ma-banque/pp/standard/db-name", 
        "LastModifiedDate": 1575848507.452, 
        "Value": "”personnephysique2”", 
        "Version": 2, 
        "Type": "SecureString", 
        "ARN": "arn:aws:ssm:eu-west-3:xxx:parameter/ma-banque/pp/standard/db-name"
    }
}

Pour lister les valeurs de l’ensemble des versions de la propriété : "/ma-banque/pp/standard/db-name" :

aws ssm get-parameter-history --with-decryption --name "/ma-banque/pp/standard/db-name"
{
    "Parameters": [
        {
            "KeyId": "alias/aws/ssm", 
            "Name": "/ma-banque/pp/standard/db-name", 
            "LastModifiedDate": 1575846351.103, 
            "Labels": [
                "v1.0.0"
            ], 
            "Value": "”personnephysique”", 
            "Version": 1, 
            "LastModifiedUser": xxx , 
            "Policies": [], 
            "Tier": "Standard", 
            "Type": "SecureString"
        }, 
        {
            "KeyId": "alias/aws/ssm", 
            "Name": "/ma-banque/pp/standard/db-name", 
            "LastModifiedDate": 1575848507.452, 
            "Labels": [
                "v1.0.1"
            ], 
            "Value": "”personnephysique2”", 
            "Version": 2, 
            "LastModifiedUser": xxx , 
            "Policies": [], 
            "Tier": "Standard", 
            "Type": "SecureString"
        }
    ]
}

Pour afficher la valeur de la propriété "/ma-banque/credit/standard" ayant le label "v1.0.0" :

aws ssm get-parameters-by-path --path /ma-banque/pp/standard --parameter-filters Key=Label,Values=v1.0.0,Option=Equals --with-decryption --recursive


{
    "Parameters": [
        {
            "Name": "/ma-banque/pp/standard/db-name", 
            "LastModifiedDate": 1575846351.103, 
            "Value": "”personnephysique”", 
            "Version": 1, 
            "Type": "SecureString", 
            "ARN": "arn:aws:ssm:eu-west-3:xxx :parameter/ma-banque/pp/standard/db-name"
        }
    ]
}

Pour afficher la valeur de la propriété "/ma-banque/credit/standard" ayant le label "v1.0.1" :

aws ssm get-parameters-by-path --path /ma-banque/pp/standard --parameter-filters Key=Label,Values=v1.0.1,Option=Equals --with-decryption --recursive
{
    "Parameters": [
        {
            "Name": "/ma-banque/pp/standard/db-name", 
            "LastModifiedDate": 1575848507.452, 
            "Value": "”personnephysique2”", 
            "Version": 2, 
            "Type": "SecureString", 
            "ARN": "arn:aws:ssm:eu-west-3:xxx:parameter/ma-banque/pp/standard/db-name"
        }
    ]
}

Conclusion



Nous avons vu dans cet article que le service AWS Systems Manager Parameter Store est bien complet et possède des fonctionnalités avancées pour la gestion de vos paramètres applicatifs. Même si les paramètres de tous vos projets sont créés dans un seul endroit, il est possible d'ajouter des métadonnées à vos paramètres permettant de les retrouver très facilement et même de pouvoir en retrouver l’historique (i.e. les anciennes valeurs).