Blog

Kontoübergreifende Bereitstellungen mit einem vom Kunden verwalteten KMS-Schlüssel

Joris Conijn

Joris Conijn

Aktualisiert Oktober 15, 2025
4 Minuten

In meinem letzten Blog habe ich über Anwendungspipelines geschrieben. Diese CodePipelines verwenden einen S3-Bucket. Was ist, wenn Sie einen vom Kunden verwalteten Schlüssel anstelle des von Amazon verwalteten Schlüssels benötigen? Und Sie möchten die CloudFormation-Vorlagen kontoübergreifend einsetzen? In diesem Blog erkläre ich Ihnen, wie Sie dies erreichen können.

Der Schlüssel selbst

Beginnen wir mit dem Schlüssel selbst. Wenn CodePipeline Artefakte von einer Stufe zu einer anderen verschiebt, verwendet es S3, um die Daten zu übertragen. Aus diesem Grund müssen wir S3 und CodePipeline erlauben, die Daten zu entschlüsseln und zu verschlüsseln:

- Action:
    - kms:Decrypt
    - kms:DescribeKey
    - kms:Encrypt
    - kms:ReEncrypt*
    - kms:GenerateDataKey*
  Effect: Allow
  Principal:
    AWS: "*"
  Resource: "*"
  Condition:
    StringEquals:
      aws:PrincipalOrgID: !Ref OrgId
      kms:ViaService:
        - Fn::Sub: s3.${AWS::Region}.amazonaws.com
        - Fn::Sub: codepipeline.${AWS::Region}.amazonaws.com

Als nächstes wird CloudFormation diese Vorlagen im gesamten Konto bereitstellen. Aus diesem Grund müssen wir CloudFormation erlauben, die Daten zu entschlüsseln.

- Action: kms:Decrypt
  Effect: Allow
  Principal:
    AWS: "*"
  Resource: "*"
  Condition:
    StringEquals:
      aws:PrincipalOrgID: !Ref OrgId
      kms:ViaService: !Sub cloudformation.${AWS::Region}.amazonaws.com

Die hier gezeigten Beispiele beschränken die Verwendung des Schlüssels auf die AWS Services innerhalb Ihrer eigenen AWS Organisation. Der S3-Bucket muss den KMS-Schlüssel für die Verschlüsselung verwenden.

Die Pipeline

Die CodePipeline muss wissen, dass wir KMS als Verschlüsselungsmethode verwenden. Aus diesem Grund müssen wir angeben, welchen Schlüssel wir verwenden wollen.

Pipeline:
  Type: AWS::CodePipeline::Pipeline
  Properties:
    ArtifactStores:
      - Region: eu-west-1
        ArtifactStore:
          Location: !Sub codepipeline-artifacts-${AWS::AccountId}-eu-west-1
          Type: S3
          EncryptionKey:
            Type: KMS
            Id: alias/bucket-key
      - Region: eu-central-1
        ArtifactStore:
          Location: !Sub codepipeline-artifacts-${AWS::AccountId}-eu-central-1
          Type: S3
          EncryptionKey:
            Type: KMS
            Id: alias/bucket-key

Wir verwenden den Alias, damit wir uns nicht um die Schlüssel-ID kümmern müssen.

Konto-/Regionsübergreifend einsetzen

Sie haben es vielleicht schon im vorigen Codeschnipsel gesehen. Wenn Sie eine regionsübergreifende Bereitstellung vornehmen, müssen Sie einen Bucket und einen Schlüssel pro Region konfigurieren. Für die kontoübergreifende Bereitstellung benötigen Sie 2 Rollen.

  1. Eine Rolle, die im anderen Konto übernommen werden soll. (kontoübergreifende Rolle, konfiguriert auf Aktionsebene)
  2. Eine Rolle, die für die CloudFormation-Ausführung verwendet wird. (cloudformation-execution-role, konfiguriert in der Konfiguration)
Actions:
  - Name: Ireland-CreateChangeSet
    Region: eu-west-1
    RunOrder: 1
    RoleArn: !Sub arn:aws:iam::${DevelopmentAccountId}:role/cross-account-role
    InputArtifacts:
      - Name: BuildArtifactAsZip
    ActionTypeId:
      Category: Deploy
      Owner: AWS
      Provider: CloudFormation
      Version: "1"
    Configuration:
      ActionMode: CHANGE_SET_REPLACE
      RoleArn: !Sub arn:aws:iam::${DevelopmentAccountId}:role/cloudformation-execution-role
      StackName: !Sub ${ProjectName}-$development
      ChangeSetName: !Sub ${ProjectName}-development-ChangeSet
      TemplatePath: BuildArtifactAsZip::packaged-template.yaml
      Capabilities: CAPABILITY_NAMED_IAM
      ParameterOverrides: |
        {
          "EnvType": "development"
        }
  - Name: Ireland-ExecuteChangeSet
    Region: eu-west-1
    RunOrder: 2
    RoleArn: !Sub arn:aws:iam::${DevelopmentAccountId}:role/cross-account-role
    ActionTypeId:
      Category: Deploy
      Owner: AWS
      Provider: CloudFormation
      Version: "1"
    Configuration:
      ActionMode: CHANGE_SET_EXECUTE
      RoleArn: !Sub arn:aws:iam::${DevelopmentAccountId}:role/cloudformation-execution-role
      StackName: !Sub ${ProjectName}-development
      ChangeSetName: !Sub ${ProjectName}-development-ChangeSet

Die kontoübergreifende Rolle muss die Fähigkeit haben, grobe Operationen auf CloudFormation durchzuführen. Sie haben Zugriff auf die Vorlagen und die Möglichkeit, die CloudFormation-Ausführungsrolle zu übergeben. Die ist die Konto-ID, die die KMS-Schlüssel, S3-Buckets und die Pipeline enthält. Diese Rolle muss in der Lage sein, auf die S3-Buckets zuzugreifen und den KMS-Schlüssel für die Entschlüsselung zu verwenden.

CrossAccountRole:
  Type: AWS::IAM::Role
  Properties:
    RoleName: cross-account-role
    AssumeRolePolicyDocument:
      Version: 2012-10-17
      Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            AWS: !Sub arn:aws:iam::${BuildAccountId}:root
    Policies:
      - PolicyName: AllowCloudFormationDeployments
        PolicyDocument:
          Version: 2012-10-17
          Statement:
            - Effect: Allow
              Action: iam:PassRole
              Resource: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cloudformation-execution-role
            - Effect: Allow
              Action: cloudformation:DescribeStacks
              Resource:
                - !Sub arn:${AWS::Partition}:cloudformation:eu-west-1:${AWS::AccountId}:stack/*
                - !Sub arn:${AWS::Partition}:cloudformation:eu-central-1:${AWS::AccountId}:stack/*
            - Effect: Allow
              Action:
                - cloudformation:CreateStack
                - cloudformation:DeleteStack
                - cloudformation:UpdateStack
                - cloudformation:CreateChangeSet
                - cloudformation:ExecuteChangeSet
                - cloudformation:DeleteChangeSet
                - cloudformation:DescribeChangeSet
                - cloudformation:SetStackPolicy
                - cloudformation:SetStackPolicy
                - cloudformation:ValidateTemplate
              Resource:
                - !Sub arn:${AWS::Partition}:cloudformation:eu-west-1:${AWS::AccountId}:stack/*
                - !Sub arn:${AWS::Partition}:cloudformation:eu-central-1:${AWS::AccountId}:stack/*
      - PolicyName: AllowArtifactAccess
        PolicyDocument:
          Version: 2012-10-17
          Statement:
            - Effect: Allow
              Action:
                - s3:GetObject
                - s3:GetObjectVersion
              Resource:
                - !Sub arn:${AWS::Partition}:s3:::codepipeline-artifacts-${BuildAccountId}-eu-west-1/*
                - !Sub arn:${AWS::Partition}:s3:::codepipeline-artifacts-${BuildAccountId}-eu-central-1/*
            - Effect: Allow
              Action: kms:Decrypt
              Resource:
                - !Sub arn:${AWS::Partition}:kms:eu-west-1:${BuildAccountId}:key/02d730ed-125b-4d2e-a498-7b0187298924
                - !Sub arn:${AWS::Partition}:kms:eu-central-1:${BuildAccountId}:key/e127b617-6951-42b7-83ae-12acc16d12a7

Die Ausführungsrolle verfügt über alle erforderlichen Rechte, um die aktuelle Vorlage bereitzustellen:

CloudFormationServiceRole:
  Properties:
    RoleName: cloudformation-execution-role
    AssumeRolePolicyDocument:
      Version: 2012-10-17
      Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal: { Service: cloudformation.amazonaws.com }
    ManagedPolicyArns:
      - !Sub arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess

Fazit

Bei der Verwendung von kundenverwalteten Schlüsseln benötigen Sie einige zusätzliche Konfigurationen. Der Schlüssel ist selbst, die Konfiguration, wo er verwendet wird und einige logische Berechtigungen. Dies alles aus der AWS-Dokumentation zu entnehmen, kann schwierig sein, da es sich um einen Sonderfall handelt.

Verfasst von

Joris Conijn

Joris is the AWS Practise CTO of the Xebia Cloud service line and has been working with the AWS cloud since 2009 and focussing on building event-driven architectures. While working with the cloud from (almost) the start, he has seen most of the services being launched. Joris strongly believes in automation and infrastructure as code and is open to learning new things and experimenting with them because that is the way to learn and grow.

Contact

Let’s discuss how we can support your journey.