Cross-Konto AWS CodePipeline nie może uzyskać dostępu CloudFormation wdrożyć artefakty

głosy
0

Mam rurociągu wielu kont działa w CI konta zmobilizowania zasobów poprzez CloudFormation na innym koncie DEV . Po wdrożeniu zapisać wyjść artefaktów jako plik JSON i chcesz uzyskać do niego dostęp w innym działaniu rurociągu poprzez CodeBuild. CodeBuild nie w DOWNLOAD_SOURCE fazy z następującym messsage:

CLIENT_ERROR: AccessDenied: Odmowa dostępu kod stanu: 403, Request-ID: 123456789, id host: xxxxx / rrrr / zzzz / xxxx = do pierwotnego źródła i wersja źródło arn AWS S3 ::: my-wiadro / my-rurociągu / DeployArti / XcUNqOP

Problemem jest to prawdopodobne, że CloudFormation, gdy są wykonywane w innym kontem, szyfrowania artefakty z innym kluczem niż samego rurociągu.

Czy to możliwe, aby dać wyraźne CloudFormation klucza KMS zaszyfrować artefakty z, lub w inny sposób jak uzyskać dostęp do tych artefaktów z powrotem w rurociągu?

Wszystko działa, gdy wykonywane od wewnątrz jednego konta.

Tu jest mój urywek kodu (rozmieszczone na koncie CI):

  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
Utwórz 19/12/2018 o 14:21
źródło użytkownik
W innych językach...                            


3 odpowiedzi

głosy
2

CloudFormation generuje wyjściowy artefakt, zamki je, a następnie przesyła plik do S3. Nie dodaje ACL, która zapewnia dostęp do właściciela wiadra. Tak, masz 403 podczas próby użyć wyjścia CloudFormation artefakt dalej wzdłuż rurociągu.

Rozwiązaniem jest jeszcze jedną akcję w swojej rurociągu natychmiast po akcji CLoudFormation dla Ex: funkcję lambda, która może przyjmować na koncie rolę docelowego i zaktualizować obiekt ACL Ex: wiadro-właściciela pełnej kontroli.

Odpowiedział 20/12/2018 o 00:34
źródło użytkownik

głosy
0

Odpowiedź mockora jest prawidłowe. Oto przykład funkcja lambda w Pythonie, który rozwiązuje problem, który można skonfigurować jako działanie Invoke natychmiast po swoim przekroju rozmieszczenia konto CloudFormation.

W tym przykładzie skonfigurowanie działania invoke ustawienia parametrów użytkownika Lambda jako ARN roli chcesz funkcja Lambda zakładać konta w zdalnym do zamocowania obiektu ACL S3. Oczywiście czynność Lambda będzie potrzebować sts:AssumeRoleuprawnień do tej roli, a pilot rola konto będzie potrzebował s3:PutObjectAcluprawnień artefaktu (ów) wiadro rurociąg.

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))}
    )
Odpowiedział 17/06/2019 o 11:31
źródło użytkownik

głosy
-1

CloudFormation należy użyć klucza szyfrowania KMS zawartych w definicji magazynu artefakt swojej rurociągu: https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_ArtifactStore.html#CodePipeline-Type-ArtifactStore-encryptionKey

Dlatego tak długo, jak dać mu klucz tam niestandardowe i pozwalają na inne konto aby używać tego klucza też powinno działać.

Jest to przede wszystkim zawarte w tym dokumencie: https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-create-cross-account.html

Odpowiedział 15/01/2019 o 00:24
źródło użytkownik

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