Saltar al contenido

¿Cómo utilizo CodePipeline para implementar un conjunto de pilas de CloudFormation StackSets administrado por servicios en una cuenta de administrador delegado?

5 minutos de lectura
0

Quiero usar AWS CodePipeline para implementar un conjunto de pilas de AWS CloudFormation StackSets destinado a las unidades organizativas (UO) de AWS Organizations. Quiero usar los permisos administrados por el servicio para implementar la pila en una cuenta de administrador delegado.

Solución

Nota: Si se muestran errores al ejecutar comandos de la Interfaz de la línea de comandos de AWS (AWS CLI), consulte Solución de problemas de AWS CLI. Además, asegúrate de utilizar la versión más reciente de la AWS CLI.

Requisito previo: Activa el acceso de confianza entre AWS CloudFormation StackSets y Organizations. Para obtener información sobre los permisos, consulta Permissions required to enable trusted access (Permisos necesarios para habilitar el acceso de confianza). Debe ser un usuario administrador en la cuenta de administración para activar el acceso de confianza.

Registro de la cuenta de administrador delegado

Para delegar una cuenta de miembro como cuenta de administrador, ejecuta el siguiente comando register-delegated-administrator de la AWS CLI:

aws organizations register-delegated-administrator \
  --service-principal=member.org.stacksets.cloudformation.amazonaws.com \
  --account-id="111122223333"

Nota: Sustituye 111122223333 por el ID de tu cuenta.

Para verificar el registro, ejecuta el siguiente comando list-delegated-administrator de la CLI:

aws organizations list-delegated-administrators \
    --service-principal=member.org.stacksets.cloudformation.amazonaws.com

Configuración de la canalización

Para crear una canalización que permita las acciones de CloudFormation, puedes usar la consola de Codepipeline o la AWS CLI.

Uso de la consola

Para usar la consola de CodePipeline para crear una canalización, consulta Create a pipeline from static templates (Crear una canalización a partir de plantillas estáticas). En Configure template (Configurar plantilla), añade la siguiente plantilla cp-template.yaml:

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  TargetRegions:
    Type: String

Resources:
  Bucket:
    Type: "AWS::S3::Bucket"
    DeletionPolicy: Retain
    Properties:
      VersioningConfiguration:
        Status: Enabled

  ServiceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codepipeline.amazonaws.com
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: CodePipelinePermissions
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:GetBucketVersioning
                  - s3:PutObject
                  - s3:PutObjectAcl
                Resource:
                  - !Sub arn:aws:s3:::${Bucket}
                  - !Sub arn:aws:s3:::${Bucket}/*
              - Effect: Allow
                Action:
                  - cloudformation:CreateStackSet
                  - cloudformation:UpdateStackSet
                  - cloudformation:DeleteStackSet
                  - cloudformation:DescribeStackSet
                  - cloudformation:DescribeStackSetOperation
                  - cloudformation:ListStackInstances
                  - cloudformation:CreateStackInstances
                Resource: "*"
              - Effect: Allow
                Action:
                  - organizations:ListDelegatedAdministrators
                Resource: "*"

  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !GetAtt ServiceRole.Arn
      ArtifactStore:
        Type: S3
        Location: !Ref Bucket
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: S3
                Version: "1"
              Configuration:
                S3Bucket: !Ref Bucket
                S3ObjectKey: "source.zip"
                PollForSourceChanges: false
              OutputArtifacts:
                - Name: SourceArtifact
        - Name: Deploy
          Actions:
            - Name: ServiceManaged-SS
              RunOrder: "1"
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CloudFormationStackSet
                Version: "1"
              Configuration:
                PermissionModel: SERVICE_MANAGED
                CallAs: DELEGATED_ADMIN
                OrganizationsAutoDeployment: Enabled
                Regions: !Ref TargetRegions
                StackSetName: !Sub codepipeline-deployed-cfn-${AWS::AccountId}-stackset
                MaxConcurrentPercentage: "50"
                FailureTolerancePercentage: "100"
                ConcurrencyMode: SOFT_FAILURE_TOLERANCE
                Capabilities: CAPABILITY_NAMED_IAM,CAPABILITY_IAM,CAPABILITY_AUTO_EXPAND
                DeploymentTargets: "SourceArtifact::ou.txt"
                TemplatePath: "SourceArtifact::template.yaml"
                Parameters: "SourceArtifact::parameters.txt"
              InputArtifacts:
                - Name: SourceArtifact

Nota: El rol de servicio de AWS Identity and Access Management (IAM) que has especificado en CallAs debe tener el permiso organizations:ListDelegatedAdministrators.

Uso de la AWS CLI

Para usar la AWS CLI para crear la canalización, consulta Create a pipeline (CLI) (Creación de una canalización [CLI]).

(Opcional) Creación de una pila

Si no usas una plantilla para crear la canalización, debes crear una pila en CloudFormation para la canalización.

Uso de la consola

Para usar la consola de CloudFormation para crear una pila, consulta Creating a stack (Creación de una pila). En la sección Parameters (Parámetros), añade las regiones de AWS en las que se implementan las instancias de StackSet. Por ejemplo, incluye aa-example-1, aa-example-2 en TargetRegions. Asegúrate de que el rol de servicio de IAM que has especificado en CallAs tenga el permiso organizations:ListDelegatedAdministrators.

Nota: Después de crear la pila, es de esperar que la canalización falle porque no has subido el archivo .zip de origen. Carga el archivo .zip después de preparar los archivos de origen.

Uso de la AWS CLI

Utiliza la misma ruta de archivo que utilizaste para cp-template.yaml y, a continuación, ejecuta el siguiente comando create-stack de la AWS CLI:

aws cloudformation create-stack \
  --stack-name stack-name \
  --capabilities CAPABILITY_NAMED_IAM \
  --template-body file://cp-template.yaml \
  --parameters ParameterKey=TargetRegions,ParameterValue=aa-example-1\\,aa-example-2

Nota: Sustituye stack-name por el nombre de la pila, //./cp-template.yaml por la ruta del archivo y aa-example-1 y aa-example-2 por tus regiones.

Carga de los archivos de origen al bucket de Amazon S3

Preparación de los archivos de origen

Para definir los destinos de implementación, crea un archivo .txt y asígnale el nombre ou.txt. Añade el siguiente código al archivo .txt:

["ou-xrop-xxxxxxxx","ou-xrop-yyyyyyyy"]

Para definir los parámetros de la plantilla de CloudFormation, crea un archivo .txt y asígnale el nombre parameters.txt. Añade el siguiente código al archivo .txt:

[
  {
    "ParameterKey": "VersioningStatus",
    "ParameterValue": "Enabled"
  }
]

Para crear la plantilla de StackSets, crea un archivo .txt y asígnale el nombre template.yaml. Añade el siguiente código al archivo .txt:

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  VersioningStatus:
    Type: String
    Default: Suspended
    AllowedValues:
      - Enabled
      - Suspended

Resources:
  S3Bucket:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Delete
    Properties:
      VersioningConfiguration:
        Status: !Ref VersioningStatus

Implementación de los archivos de origen

Comprime los tres archivos en source.zip y, a continuación, carga el archivo .zip en el directorio raíz del bucket de Amazon Simple Storage Service (Amazon S3) de origen. Si la canalización falla y recibes el error "Account used is not a delegated administrator", confirma que has registrado la cuenta como administrador delegado.

Información relacionada

AWS CloudFormation StackSets deploy action reference (Referencia de la acción de implementación de AWS CloudFormation StackSets)

How do I resolve the error when I run the ListStackSets operation?"Account used is not a delegated administrator" (¿Cómo soluciono el error al ejecutar la operación ListStackSets?)

OFICIAL DE AWSActualizada hace un año