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:
- org-root@example.com
- project-prod@example.com
- project-stage@example.com
- project-qa@example.com
- project-dev@example.com
- etc.
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 ?
- Augmenter le niveau de sécurité à travers les environnements (en procurant l’isolation entre les environnements)
- Favoriser l’usage de l’infrastructure as code (CloudFormation et SAM)
- Utiliser les free tiers pour chaque compte AWS
- Utiliser le concept de “least privileges”
- Centraliser les usagers et permissions
- Utiliser les profile AWS pour accéder aux différents comptes et ressources. (Assume role)
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
- 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
- Ensuite il faut créer une organisation
Voir photos
- 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)
- Créer le Groupe Administrators dans le compte org-root
- Créez le premier usager et assignez-le dans le groupe Administrators
- 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
- Créer un rôle
- Choisir
Another AWS Account
pour leType of trusted entity
- entrer le numéro de compte du trusted account.
- Choisir le/les policies désirées.
- Choisir des tags appropriés selon la politique de votre entreprise.
- Donner un nom à votre nouveau rôle.
Trusted Account
Policy
- Créer une nouvelle policy.
- Choisir le service STS.
- Puis ajouter la permission AssumeRole.
- Ensuite, spécifiez un ARN pour cette policy, cliquez sur
add ARN
. - Entrer le account id du trusting account.
- Entrer le nom du rôle précédemment créé.
- Donner un nom à votre policy, par exemple
AssumeRoleSpecification
Groupe
- Créer un nouveau groupe.
- Donnez-lui un nom, par exemple
SpecificationAssumeRoleGroup
. - Ajouter la policy précédemment créée à ce groupe.
Usager
- 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
- Compte AWS pour Développement :
123456789012
- Compte AWS pour Production :
234567890123
- Compte AWS pour les usagers de l’organisation :
098765432112
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
- À partir du compte org-root, connectez-vous avec votre compte AWS.
- Pour ajouter les rôles la première fois, vous devez cliquer sur switch role
- Entrer le nom ou numéro de compte sur lequel vous voulez vous connecter. (par exemple:
project-dev
) - Entrer le nom du rôle que vous voulez utiliser (par exemple:
DeveloperRole
) - Vous pouvez choisir un nom et une couleur.
- Cliquez sur Switch Role
Vous devez voir la barre en haut à droite avec quelque chose comme ceci:
Sources
- https://chariotsolutions.com/blog/post/managing-aws-users-and-roles-in-a-multi-account-organization/
- https://www.youtube.com/watch?v=20tr9gUY4i0
- https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-cli.html
- https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#awsmp_readonlyaccess