Comment utiliser CodePipeline pour déployer une pile AWS CloudFormation dans un autre compte ?

Date de la dernière mise à jour : 09/12/2019

Comment utiliser AWS CodePipeline pour déployer une pile AWS CloudFormation dans un autre compte ?

Brève description

Pour déployer une pile AWS CloudFormation dans un autre compte, vous devez effectuer les opérations suivantes :

  1. Créez un pipeline dans un premier compte dénommé compte A. Ce compte doit inclure une clé AWS Key Management Service (AWS KMS) gérée par le client, un compartiment Amazon Simple Storage Service (Amazon S3) pour les artefacts et une stratégie de compartiment S3 qui autorise l’accès depuis l’autre compte dénommé compte B.
  2. Dans le compte B, configurez un rôle de service entre comptes qui autorise les éléments suivants : 1) actions AWS CloudFormation, 2) accès au compartiment S3 dans le compte A, et 3) déchiffrement avec la clé KMS gérée par le client dans le compte A.
  3. Dans le compte A, autorisez un rôle de service de pipeline à jouer un rôle entre comptes (avec AssumeRole) dans le compte B.

Solution

Dans le compte A, créez une clé gérée par le client

1.    Dans le compte A, ouvrez la console AWS KMS.

2.    Dans le volet de navigation, choisissez Customer managed keys (Clés gérées par le client).

3.    Choisissez Create key (Créer une clé), puis Symmetric (Symétrique).

Remarque : dans la section Advanced options (Options avancées), conservez l’originale en tant que KMS.

4.    Pour Alias, entrez un nom pour votre clé.

5.    (Facultatif) Ajoutez des balises, puis choisissez Next (Suivant).

6.    Sur la page Define key administrative permissions (Définir des autorisations administratives de clé), pour Key administrators (Administrateurs de clé), choisissez votre utilisateur AWS Identity and Access Management (IAM) et tous les autres utilisateurs ou groupes que vous souhaitez affecter en tant qu’administrateurs de la clé, puis choisissez Next(Suivant).

7.    Sur la page Define key usage permissions (Définir les autorisations d’autorisation de clé) pour This account (Ce compte), ajoutez les utilisateurs IAM du compte qui doivent avoir accès à la clé (par exemple, le rôle de service CodePipeline).

8.    Dans la section Other AWS accounts (Autres comptes AWS), choisissez Add another AWS account (Ajouter un autre compte AWS), puis saisissez le nom Amazon Resource Name (ARN) du rôle IAM dans le compte B.

9.    Sélectionnez Next (Suivant), puis Finish (Terminer).

10.    Dans la section Customer managed keys (Clés gérées par le client), choisissez la clé que vous venez de créer, puis copiez le nom ARN de cette clé.

Remarque : vous devez avoir le nom ARN de votre clé pour modifier le pipeline et configurer vos stratégies.

Dans le compte A, sélectionnez ou créez un compartiment Amazon S3 en tant que pipeline du compartiment SourceArtifact, puis créez une stratégie de compartiment

Votre stratégie de compartiment S3 dans le compte A doit autoriser l’accès pour le compte B.

1.    Dans le compte A, ouvrez la console Amazon S3.

2.    Choisissez un compartiment S3 existant ou créez un nouveau compartiment S3 à utiliser comme ArtifactStore pour CodePipeline.

Remarque : les artefacts peuvent inclure un fichier de modèle de pile, un fichier de configuration de modèle ou les deux. CodePipeline utilise ces artefacts pour travailler avec les piles et les jeux de modifications AWS CloudFormation. Dans votre fichier de configuration de modèle, vous devez spécifier les valeurs des paramètres du modèle, une stratégie de pile et des balises.

3.    Sur la page détails Amazon S3 du compartiment, choisissez Permissions (Autorisations).

4.    Sélectionnez Stratégie de compartiment.

5.    Dans l’éditeur de stratégie de compartiment, saisissez le code suivant :

{
  "Id": "Policy1553183091390",
  "Version": "2012-10-17",
  "Statement": [{
      "Sid": "",
      "Action": [
        "s3:Get*",
        "s3:Put*"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::codepipeline-source-artifact/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::ACCOUNT_B_NO:root"
        ]
      }
    },
    {
      "Sid": "",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::codepipeline-source-artifact",
      "Principal": {
        "AWS": [
          "arn:aws:iam::ACCOUNT_B_NO:root"
        ]
      }
    }
  ]
}

6.    Dans le code précédent, remplacez codepipeline-source-artifact par le nom de compartiment SourceArtifact pour CodePipeline.

7.    Dans le code précédent, remplacez ACCOUNT_B_NO par le numéro du compte B.

8.    Sélectionnez Save (Enregistrer).

Dans le compte B, créez un rôle entre comptes (CROSS_ACCOUNT_ROLE) qui autorise les actions liées à S3 et KMS dans SourceArtifact pour le compte A.

La stratégie de rôle entre comptes permet au pipeline du compte A d’assumer un rôle dans le compte B. Cette stratégie active également les actions AWS CloudFormation et l’accès aux opérations liées à SourceArtifact et KMS.

1.    Dans le compte B, ouvrez la console IAM.

2.    Dans le volet de navigation, choisissez Policies (Stratégies).

3.    Choisissez Create policy (Créer une stratégie).

4.    Choisissez la vue JSON, puis saisissez la stratégie suivante dans l’éditeur de code :

{
  "Version": "2012-10-17",
  "Statement": [{
      "Effect": "Allow",
      "Action": [
        "cloudformation:*",
        "iam:PassRole"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:Get*",
        "s3:Put*",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::codepipeline-source-artifact/*"
      ]
    }
  ]
}

5.    Dans le code précédent, remplacez codepipeline-source-artifact par le nom de compartiment ArtifactStore du pipeline.

6.    Choisissez Review policy (Vérifier la stratégie), puis créez la stratégie.

7.    Dans le volet de navigation, choisissez Policies (Stratégies).

8.    Choisissez Create policy (Créer une stratégie).

9.    Choisissez la vue JSON, puis saisissez la stratégie suivante dans l’éditeur de code :

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "kms:DescribeKey",
      "kms:GenerateDataKey*",
      "kms:Encrypt",
      "kms:ReEncrypt*",
      "kms:Decrypt"
    ],
    "Resource": [
      "arn:aws:kms:REGION:ACCOUNT_A_NO:key/key-id"
    ]
  }]
}

10.    Dans le code précédent, remplacez arn:aws:kms:REGION:ACCOUNT_A_NO:key/key-id par le nom ARN de la clé que vous avez créée précédemment dans la section Create a customer managed key in account A « Créer une clé gérée par le client pour le compte A ».

11.    Choisissez Review policy (Vérifier la stratégie), puis créez la stratégie.

12.    Dans le volet de navigation, choisissez Roles (Rôles).

13.    Choisissez Create role (Créer un rôle).

14.    Choisissez Another AWS account (Autre compte AWS).

15.    Pour Account ID (ID du compte), saisissez l’ID du Compte A.

16.    Choisissez Next: Permissions (Étape suivante : autorisations), puis suivez les étapes pour créer le rôle.

17.    Associez au rôle que vous avez créé la stratégie de rôle entre comptes et la stratégie de clé KMS.

Dans le compte A, ajoutez l’autorisation AssumeRole au rôle de service CodePipeline.

Votre stratégie autorise le rôle de service CodePipeline du compte A à assumer le rôle entre comptes que vous avez créé précédemment dans le compte B.

1.    Dans le compte A, ouvrez la console IAM.

2.    Dans le volet de navigation, choisissez Roles (Rôles).

3.    Choisissez le rôle de service IAM que vous utilisez pour CodePipeline.

4.    Sélectionnez Add inline policy (Ajouter une stratégie en ligne).

5.    Choisissez la vue JSON, puis saisissez la stratégie suivante dans l’éditeur de code :

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": [
      "arn:aws:iam::ACCOUNT_B_NO:role/*"
    ]
  }
}

6.    Dans le code précédent, remplacez ACCOUNT_B_NO  par le numéro du compte B.

7.    Choisissez Review policy (Vérifier la stratégie), puis créez la stratégie.

Dans le compte B, créez un rôle pour la pile AWS CloudFormation (CFN_STACK_ROLE).

Ce rôle de service est directement configuré sur la pile AWS CloudFormation dans le compte B et doit inclure les autorisations pour les services déployés par la pile.

1.    Dans le compte B, ouvrez la console IAM.

2.    Dans le volet de navigation, choisissez Roles (Rôles).

3.    Créez un rôle pour AWS CloudFormation à utiliser lors du lancement des services en votre nom.

4.    Appliquez les autorisations à votre rôle en fonction de vos besoins.

Important : vérifiez que la stratégie d’approbation est destinée à AWS CloudFormation et que votre rôle est autorisé à accéder aux services déployés par la pile.

Dans le compte A, mettez à jour la configuration CodePipeline.

Remarque : vous ne pouvez pas utiliser la console CodePipeline pour créer ou modifier un pipeline qui utilise les ressources associées à un autre compte. Toutefois, vous pouvez utiliser la console pour créer la structure générale du pipeline. Ensuite, vous pouvez utiliser l’interface de ligne de commande AWS (AWS CLI) pour modifier le pipeline et ajouter les ressources associées à l’autre compte. Ou bien, vous pouvez mettre à jour un pipeline en cours avec les ressources du nouveau pipeline.

1.    Dans l’interface de ligne de commande AWS, exécutez la commande suivante pour obtenir la structure JSON du pipeline :

aws codepipeline get-pipeline --name MyFirstPipeline >pipeline.json

2.    Dans votre fichier pipeline.json local, vérifiez que l’ID encryptionKey contient l’ID avec le nom ARN de la clé que vous avez créée précédemment.

3.    Dans le fichier pipeline.json , mettez à jour la configuration d’action AWS CloudFormation.

Remarque : RoleArn dans la structure JSON de la configuration d’action du pipeline est le rôle pour la pile AWS CloudFormation (CFN_STACK_ROLE). roleArn en dehors de la structure JSON de la configuration d’action est le rôle entre comptes que le pipeline assume pour exploiter une pile AWS CloudFormation (CROSS_ACCOUNT_ROLE).

4.    Vérifiez que le rôle est mis à jour pour RoleArn et roleArn.

Dans l’exemple de code suivant, RoleArn est le rôle transmis à AWS CloudFormation pour lancer la pile. CodePipeline utilise roleArn pour exploiter une pile AWS CloudFormation.

{
  "name": "Prod_Deploy",
  "actions": [{
    "inputArtifacts": [{
      "name": "MyApp"
    }],
    "name": "test-cfn-x",
    "actionTypeId": {
      "category": "Deploy",
      "owner": "AWS",
      "version": "1",
      "provider": "CloudFormation"
    },
    "outputArtifacts": [],
    "configuration": {
      "ActionMode": "CHANGE_SET_REPLACE",
      "ChangeSetName": "test",
      "RoleArn": "ARN_FOR_CFN_STACK_ROLE",
      "Capabilities": "CAPABILITY_IAM",
      "StackName": "test-cfn-sam",
      "TemplatePath": "MyApp::template.yaml"
    },
    "roleArn": "ARN_FOR_CROSS_ACCOUNT_ROLE",
    "runOrder": 1
  }]
}

5.    Supprimez la configuration metadata du fichier pipeline.json :

"metadata": {
  "pipelineArn": "arn:aws:codepipeline:REGION:ACC:my_test",
  "updated": 1551216777.183,
  "created": 1551207202.964
}

Important : pour respecter le formatage JSON approprié, supprimez la virgule avant la section metadata .

6.    (Facultatif) Pour créer un pipeline et mettre à jour la structure JSON, exécutez la commande suivante pour mettre à jour le pipeline avec le nouveau fichier de configuration :

aws codepipeline update-pipeline --cli-input-json file://pipeline.json

7.    (Facultatif) Pour utiliser un pipeline en cours et mettre à jour la structure JSON, exécutez la commande suivante pour créer un nouveau pipeline :

aws codepipeline create-pipeline --cli-input-json file://pipeline.json

Remarque : dans votre fichier pipeline.json, modifiez le nom de votre nouveau pipeline.