Webux Lab

Par Studio Webux

Plusieurs comptes AWS avec une organisation

TG
Tommy Gingras Studio Webux S.E.N.C 2021-07-20

Introduction

L’objectif de cet article est de partager une façon de gérer plusieurs environnements, tels que Développement, QA, Stage et Production en utilisant plusieurs comptes AWS.
De plus, les usagers seront gérés à un seul endroit pour garder le tout simple à maintenir.

L’article suivant explique très bien les concepts : managing-aws-users-and-roles-in-a-multi-account-organization


Première partie

Requis

Il faut des adresses courriel uniques pour créer les différents comptes AWS,

Par exemple:

Un numéro de téléphone et Carte de crédit.

Compte AWS

Création d'un compte AWS (Photos)

Vous pouvez maintenant vous connecter en tant que ‘root’ en utilisant les informations que vous avez fournies.

Très important de créer un usager et un groupe administrateur puis sécuriser le compte root avec un bon mot de passe et si vous voulez, configurez MFA pour un extra de sécurité.


Les permissions IAM

La bonne pratique est de donner le moins de permissions et d’ajuster ceux-ci au besoin. (Least privileges)
Ceci dit, voici une solution proposée:

Compte de Production & Staging

(incluant Préproduction s’il y a lieu)

  • Administrators Access
  • Monitoring & Logs Access
  • Databases Access
  • Lambda Access
  • API Access
  • Containers Access
  • DNS Access
  • Network Access

Donc un usager peut avoir les permissions limitées pour accéder aux ressources selon son rôle et responsabilité.

Compte de QA
  • Administrators Access
  • Monitoring & Logs Access
  • Developers Access (Lecture seulement)
  • Pipeline Access (Permissions pour déployer avec CodePipeline ou autres)

Les développeurs ne doivent pas déployer dans ce compte directement, le Continuous Delivery va se charger de cette tâche.

Compte de Dévelopement
  • Administrators Access
  • Monitoring & Logs Access
  • Developers Access (Lecture et écriture selon la politique de l’entreprise. Il est préférable de ne pas modifier les ressources manuellement pour éviter de créer des conflits (a.k.a Drifts))
  • Pipeline Access (Permissions pour déployer avec CodePipeline ou autres)

Selon votre politique d’entreprise, ce compte est partagé à tous les développeurs, QA et autres équipes de travail. Selon comment vous gérez votre Infrastructure as Code, il est important de bien définir l’approche désirée pour déployer les nouvelles ressources. Mon point de vue; il est important de garder les fichiers CloudFormation à jour, par contre il est aussi important que les développeurs puissent tester rapidement les nouvelles fonctionnalités. (Voir plus bas pour une solution)

Compte Sandbox

(selon l’entreprise et la quantité de développeurs, vous pouvez avoir plusieurs sandboxes)

  • Administrators Access
  • Developers Access (Power User, ce compte sert pour tester, donc les développeurs peuvent faire pas mal tout directement.)
  • Pipeline Access (Permissions pour déployer avec CodePipeline ou autres)

Ces comptes sont disponibles à chaque développeur et donc permettent de tester des branches de feature de façon complètement isolée. De plus les développeurs peuvent tester rapidement et ensuite exporter/écrire les CloudFormations requis.


Donc selon l’environnement, un usager doit sélectionner (et être autorisé) à faire certaines actions. De cette façon nous pouvons contrôler les accès facilement et efficacement pour tous les comptes.

L’objectif final est d’éviter les erreurs et mauvaises manipulations.


Pourquoi tout ça ?


Deuxième partie

Maintenant, comment mettre tout ça en pratique ?

On va commencer avec la configuration de l’organisation root account (aka org-root account)

Création de l’organisation
  1. Pour ce faire créer un nouveau compte AWS (org-root) en utilisant votre courriel unique (org-root@example.com). (Je prend pour acquis que vous n’avez pas de compte ni d’organisation de créé) ( Fait à l’étape précédente )
Bonus pour activer l'accès aux billing utilisant un usager IAM

Cliquez sur My Account


  1. Ensuite il faut créer une organisation
Voir photos


  1. Inviter les comptes existants ou créer les nouveaux comptes en utilisant les adresses courriel appropriées

Configuration IAM

Voir plus bas pour utiliser CloudFormation pour la création du groupe administrateur (vous pouvez aussi le faire manuellement)

  1. Créer le Groupe Administrators dans le compte org-root
  2. Créez le premier usager et assignez-le dans le groupe Administrators
  3. Complétez l’ajout des comptes AWS invité à votre organisation, en vous connectant dans chacun d’eux et en acceptant l’invitation reçue par courriel.

Création des Rôles et Policies

Version courte (CloudFormation)

CloudFormation
AWSTemplateFormatVersion: 2010-09-09
Description: IAM Roles, Policies, Groups and Users

Parameters:
  IsTrustedAccount:
    Type: String
    AllowedValues:
      - "true"
      - "false"
    Default: "false"
  IsTrustingAccount:
    Type: String
    AllowedValues:
      - "true"
      - "false"
    Default: "false"

  DeveloperReadOnly:
    Type: String
    AllowedValues:
      - "true"
      - "false"
    Default: "false"

  TrustedAccountId:
    Type: String
    Default: ""
  TrustingAccountId:
    Type: String
    Default: ""

Conditions:
  isTrustedAccount: !Equals [!Ref IsTrustedAccount, "true"]
  isTrustingAccount: !Equals [!Ref IsTrustingAccount, "true"]
  developerReadOnly: !Equals [!Ref DeveloperReadOnly, "true"]

Resources:
  AdministratorsGroup:
    Condition: isTrustedAccount
    Type: AWS::IAM::Group
    Properties:
      GroupName: Administrators
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AdministratorAccess
      Path: /

  AdministratorsAssumeRole:
    Condition: isTrustedAccount
    Type: AWS::IAM::Group
    Properties:
      GroupName: AdministratorsAssumeRole
      ManagedPolicyArns:
        - !Ref AdministratorAssumePolicy
      Path: /

  DevelopersAssumeRole:
    Condition: isTrustedAccount
    Type: AWS::IAM::Group
    Properties:
      GroupName: DevelopersAssumeRole
      ManagedPolicyArns:
        - !Ref DeveloperAssumePolicy
      Path: /

  AdministratorAssumePolicy:
    Condition: isTrustedAccount
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: AdministratorAssumeRole
      Path: /
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action: "sts:AssumeRole"
            Resource:
              - !Join
                - ""
                - - "arn:aws:iam::"
                  - !Select [0, !Split [",", !Ref TrustingAccountId]]
                  - ":role/AdministratorRole"
              - !Join
                - ""
                - - "arn:aws:iam::"
                  - !Select [1, !Split [",", !Ref TrustingAccountId]]
                  - ":role/AdministratorRole"
              # Ajouter les autres comptes de la même façon

  DeveloperAssumePolicy:
    Condition: isTrustedAccount
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: DeveloperAssumeRole
      Path: /
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action: "sts:AssumeRole"
            Resource:
              - !Join
                - ""
                - - "arn:aws:iam::"
                  - !Select [0, !Split [",", !Ref TrustingAccountId]]
                  - ":role/DeveloperRole"
              - !Join
                - ""
                - - "arn:aws:iam::"
                  - !Select [1, !Split [",", !Ref TrustingAccountId]]
                  - ":role/DeveloperRole"
              # Ajouter les autres comptes de la même façon

  # Vous pouvez changer les permissions selon le compte
  AdministratorRole:
    Condition: isTrustingAccount
    Type: AWS::IAM::Role
    Properties:
      RoleName: AdministratorRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          Effect: "Allow"
          Principal:
            AWS: !Sub "arn:aws:iam::${TrustedAccountId}:root"
          Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AdministratorAccess"

  # Vous pouvez changer les permissions selon le compte
  # Par exemple, sur production vous voulez peut-être mettre lecture seulement au lieu de power user
  DeveloperRole:
    Condition: isTrustingAccount
    Type: AWS::IAM::Role
    Properties:
      RoleName: DeveloperRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          Effect: "Allow"
          Principal:
            AWS: !Sub "arn:aws:iam::${TrustedAccountId}:root"
          Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - !If
          - developerReadOnly
          - "arn:aws:iam::aws:policy/ReadOnlyAccess"
          - "arn:aws:iam::aws:policy/PowerUserAccess"

  BillingRole:
    Condition: isTrustingAccount
    Type: AWS::IAM::Role
    Properties:
      RoleName: BillingRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          Effect: "Allow"
          Principal:
            AWS: !Sub "arn:aws:iam::${TrustedAccountId}:root"
          Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/Billing"
Scripts
PROFILE=org-root
REGION=ca-central-1

echo "Deploy IAM Stack"
aws cloudformation deploy \
  --profile=$PROFILE \
  --region=$REGION \
  --template-file "./IAM.yaml" \
  --stack-name "org-root-iam" \
  --capabilities CAPABILITY_NAMED_IAM \
  --tags \
    Project="Global" \
  --parameter-overrides \
    TrustingAccountId="123456789012,234567890123" \
    TrustedAccountId="098765432112" \
    IsTrustedAccount="true"

aws cloudformation update-termination-protection \
  --profile=$PROFILE \
  --region=$REGION \
  --stack-name "org-root-iam" \
  --enable-termination-protection
PROFILE=studiowebux
REGION=ca-central-1

aws cloudformation deploy \
  --profile=$PROFILE \
  --region=$REGION \
  --template-file "./IAM.yaml" \
  --stack-name "iam-123456789012" \
  --capabilities CAPABILITY_NAMED_IAM \
  --tags \
    Project="Production" \
  --parameter-overrides \
    TrustingAccountId="123456789012" \
    TrustedAccountId="098765432112" \
    IsTrustingAccount="true" \
    DeveloperReadOnly="true"

aws cloudformation update-termination-protection \
  --profile=$PROFILE \
  --region=$REGION \
  --stack-name "iam-123456789012" \
  --enable-termination-protection
PROFILE=webuxlab
REGION=ca-central-1

aws cloudformation deploy \
  --profile=$PROFILE \
  --region=$REGION \
  --template-file "./IAM.yaml" \
  --stack-name "iam-234567890123" \
  --capabilities CAPABILITY_NAMED_IAM \
  --tags \
    Project="Development" \
  --parameter-overrides \
    TrustingAccountId="234567890123" \
    TrustedAccountId="098765432112" \
    IsTrustingAccount="true"

aws cloudformation update-termination-protection \
  --profile=$PROFILE \
  --region=$REGION \
  --stack-name "iam-234567890123" \
  --enable-termination-protection

Version longue (manuelle)

Voir détails

Il faut identifier deux types de comptes.

  • Trusted Account (org-root)
    • Ce compte contient tous les usagers.
  • Trusting Account (les autres comptes)
    • Ces comptes contiennent les différents services AWS.
    • Puis les Rôles et Permissions qui seront assumés par les usagers du trusted account.

Trusting Account

  1. Créer un rôle
  2. Choisir Another AWS Account pour le Type of trusted entity
  3. entrer le numéro de compte du trusted account.
  4. Choisir le/les policies désirées.
  5. Choisir des tags appropriés selon la politique de votre entreprise.
  6. Donner un nom à votre nouveau rôle.

Trusted Account

Policy
  1. Créer une nouvelle policy.
  2. Choisir le service STS.
  3. Puis ajouter la permission AssumeRole.
  4. Ensuite, spécifiez un ARN pour cette policy, cliquez sur add ARN.
  5. Entrer le account id du trusting account.
  6. Entrer le nom du rôle précédemment créé.
  7. Donner un nom à votre policy, par exemple AssumeRoleSpecification
Groupe
  1. Créer un nouveau groupe.
  2. Donnez-lui un nom, par exemple SpecificationAssumeRoleGroup.
  3. Ajouter la policy précédemment créée à ce groupe.
Usager
  1. Ajouter les différents usagers à ce nouveau groupe.

Répéter les étapes pour chaque rôle.


Tester la configuration

Le fichier credentials

~/.aws/credentials

Contenu du fichier credentials
[org-root]
aws_access_key_id=AKIAXYZ...
aws_secret_access_key=XYZABCXYZABC...

[webux-admin-dev]
role_arn = arn:aws:iam::123456789012:role/AdministratorRole
source_profile = org-root

[webux-admin-prod]
role_arn = arn:aws:iam::0987654321123:role/AdministratorRole
source_profile = org-root

[webux-dev-dev]
role_arn = arn:aws:iam::123456789012:role/DeveloperRole
source_profile = org-root

[webux-dev-prod]
role_arn = arn:aws:iam::0987654321123:role/DeveloperRole
source_profile = org-root

Les commandes AWS CLI

Connectez-vous en tant que l’usager configuré précédemment pour tester le Assume Role.

Vous devez utiliser le account id du trusting account (donc celui de Développement, Production et autres) suivi du rôle que vous voulez assumer.

Les deux commandes suivantes doivent vous montrer les usagers dans les différents comptes (si des usagers sont présents, vous pouvez aussi utiliser n’importe quelle autre commande)

aws iam list-users --profile webux-admin-prod
aws iam list-users --profile webux-admin-dev

Ces deux commandes doivent retourner une erreur (car leurs permissions ne permettent pas IAM)

aws iam list-users --profile webux-dev-prod
aws iam list-users --profile webux-dev-dev

Troisième partie

En utilisant le UI de AWS,

Changer de rôle temporairement

Voici un exemple du menu pour changer de rôle temporairement,

L’exemple ci-dessous montre tous les rôles. Puis seulement les DeveloperRole fonctionnent pour l’usager connecté.

Ajouter les autres rôles

  1. À partir du compte org-root, connectez-vous avec votre compte AWS.
  2. Pour ajouter les rôles la première fois, vous devez cliquer sur switch role
  3. Entrer le nom ou numéro de compte sur lequel vous voulez vous connecter. (par exemple: project-dev)
  4. Entrer le nom du rôle que vous voulez utiliser (par exemple: DeveloperRole)
  5. Vous pouvez choisir un nom et une couleur.
  6. Cliquez sur Switch Role

Vous devez voir la barre en haut à droite avec quelque chose comme ceci:


Sources


Recherche