Cross-Konto AWS CodePipeline keinen Zugriff auf Cloudformation Artefakte bereitstellen

stimmen
0

Ich habe eine Quer Konto Pipeline in einem Konto CI laufenden Ressourcen über die Bereitstellung von Cloudformation in einem anderen Konto DEV . Ich speichere die Artefakt - Ausgänge als JSON - Datei Nach der Bereitstellung und wollen über CodeBuild es in einer anderen Pipeline - Aktion aufzurufen. CodeBuild nicht in der Phase DOWNLOAD_SOURCE mit folgendem messsage:

CLIENT_ERROR: AccessDenied: Zugriff verweigert Statuscode: 403, Anfrage-ID: 123456789, Host-ID: xxxxx / yyyy / zzzz / xxxx = für primäre Quelle und Source-Version arn: aws: s3 ::: my-Eimer / my-Pipeline / DeployArti / XcUNqOP

Das Problem ist wahrscheinlich, dass die Cloudformation, wenn sie in einem anderen Konto ausgeführt wird, selbst die Artefakte mit einem anderen Schlüssel als die Pipeline verschlüsseln.

Ist es möglich, der Cloudformation einen expliziten KMS-Schlüssel zu geben, die Artefakte mit, oder jede andere Art und Weise zu verschlüsseln, wie diese Artefakte zurück in der Pipeline zugreifen?

Alles funktioniert, wenn aus einem einzigen Konto ausgeführt.

Hier ist mein Code-Schnipsel (im CI-Konto eingesetzt):

  MyCodeBuild:
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Environment: ...
      Name: !Sub my-codebuild
      ServiceRole: !Ref CodeBuildRole
      EncryptionKey: !GetAtt KMSKey.Arn
      Source:
        Type: CODEPIPELINE
        BuildSpec: ...

  CrossAccountCodePipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      Name: my-pipeline
      RoleArn: !GetAtt CodePipelineRole.Arn
      Stages:
      - Name: Source
        ...
      - Name: StagingDev
        Actions:
        - Name: create-stack-in-DEV-account
          InputArtifacts:
          - Name: SourceArtifact
          OutputArtifacts:
          - Name: DeployArtifact
          ActionTypeId:
            Category: Deploy
            Owner: AWS
            Version: 1
            Provider: CloudFormation
          Configuration:
            StackName: my-dev-stack
            ChangeSetName: !Sub my-changeset
            ActionMode: CREATE_UPDATE
            Capabilities: CAPABILITY_NAMED_IAM
            # this is the artifact I want to access from the next action 
            # within this CI account pipeline
            OutputFileName: my-DEV-output.json   
            TemplatePath: !Sub SourceArtifact::stack/my-stack.yml
            RoleArn: !Sub arn:aws:iam::${DevAccountId}:role/dev-cloudformation-role
          RoleArn: !Sub arn:aws:iam::${DevAccountId}:role/dev-cross-account-role
          RunOrder: 1
        - Name: process-DEV-outputs
          InputArtifacts:
          - Name: DeployArtifact
          ActionTypeId:
            Category: Build
            Owner: AWS
            Version: 1
            Provider: CodeBuild
          Configuration:
            ProjectName: !Ref MyCodeBuild
          RunOrder: 2
      ArtifactStore:
        Type: S3
        Location: !Ref S3ArtifactBucket
        EncryptionKey:
          Id: !GetAtt KMSKey.Arn
          Type: KMS
Veröffentlicht am 19/12/2018 um 14:21
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
2

Cloudformation erzeugt Ausgangs Artefakt, Reißverschlüsse es und lädt dann die Datei auf S3. Es fügt keine ACL, die den Zugriff auf den heißen Stein Eigentümer gewährt. So erhalten Sie einen 403, wenn Sie versuchen, die Cloudformation Ausgabe verwenden Artefakt weiter unten in der Pipeline.

Abhilfe ist eine weitere Aktion in Ihrer Pipeline unmittelbar nach Cloudformation Aktion für die Ex haben: Lambda-Funktion, die das Zielkonto Rolle übernehmen kann und das Objekt acl ex aktualisieren: eimer Inhaber-full-Kontrolle.

Beantwortet am 20/12/2018 um 00:34
quelle vom benutzer

stimmen
0

mockora Antwort ist richtig. Hier ist ein Beispiel Lambda-Funktion in Python, das das Problem behebt, die Sie als Invoke Aktion unmittelbar nach dem Quer Konto Cloudformation Bereitstellung konfigurieren können.

In diesem Beispiel konfigurieren Sie die Lambda invoke Aktion Benutzerparameter Einstellung , die als ARN der Rolle , die Sie die Lambda - Funktion in Remote - Konto zu übernehmen wollen das S3 - Objekt ACL zu beheben. Offensichtlich Ihre Lambda - Funktion müssen sts:AssumeRoleBerechtigungen für diese Rolle, und die Remote - Konto Rolle müssen s3:PutObjectAclBerechtigungen für die Pipeline Eimer Artefakt (n).

import os
import logging, datetime, json
import boto3
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

# X-Ray
patch_all()

# Configure logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(os.environ.get('LOG_LEVEL','INFO'))
def format_json(data):
  return json.dumps(data, default=lambda d: d.isoformat() if isinstance(d, datetime.datetime) else str(d))

# Boto3 Client
client = boto3.client
codepipeline = client('codepipeline')
sts = client('sts')

# S3 Object ACLs Handler
def s3_acl_handler(event, context):
  log.info(f'Received event: {format_json(event)}')
  # Get Job
  jobId = event['CodePipeline.job']['id']
  jobData = event['CodePipeline.job']['data']
  # Ensure we return a success or failure result
  try:
    # Assume IAM role from user parameters
    credentials = sts.assume_role(
      RoleArn=jobData['actionConfiguration']['configuration']['UserParameters'],
      RoleSessionName='codepipeline',
      DurationSeconds=900
    )['Credentials']
    # Create S3 client from assumed role credentials
    s3 = client('s3',
      aws_access_key_id=credentials['AccessKeyId'],
      aws_secret_access_key=credentials['SecretAccessKey'],
      aws_session_token=credentials['SessionToken']
    )
    # Set S3 object ACL for each input artifact
    for inputArtifact in jobData['inputArtifacts']:
      s3.put_object_acl(
        ACL='bucket-owner-full-control',
        Bucket=inputArtifact['location']['s3Location']['bucketName'],
        Key=inputArtifact['location']['s3Location']['objectKey']
      )
    codepipeline.put_job_success_result(jobId=jobId)
  except Exception as e:
    logging.exception('An exception occurred')
    codepipeline.put_job_failure_result(
      jobId=jobId,
      failureDetails={'type': 'JobFailed','message': getattr(e, 'message', repr(e))}
    )
Beantwortet am 17/06/2019 um 11:31
quelle vom benutzer

stimmen
-1

Cloudformation sollte den KMS - Verschlüsselungsschlüssel in dem Artefakt speichern Definition Ihrer Pipeline bereitgestellt verwenden: https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_ArtifactStore.html#CodePipeline-Type-ArtifactStore-encryptionKey

Deshalb, so lange wie Sie ihm einen benutzerdefinierten Schlüssel dort geben und dem andere Konto erlauben auch den Schlüssel zu verwenden, sollte es funktionieren.

Dies ist vor allem in diesem Dokument behandelt: https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-create-cross-account.html

Beantwortet am 15/01/2019 um 00:24
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more