Zum Hauptinhalt springen

Continuous Delivery mit AWS CodePipeline

Tobias Jonas Tobias Jonas 3 min Lesezeit
Continuous Delivery mit AWS CodePipeline

Continuous Delivery ist ein essenzieller Bestandteil moderner Softwareentwicklung. AWS bietet mit CodePipeline, CodeBuild und CodeDeploy ein vollständiges CI/CD-Ökosystem. In diesem Beitrag zeigen wir, wie man eine Deployment-Pipeline für eine Scala-Anwendung aufsetzt.

AWS DevOps Tools im Überblick

AWS CodePipeline

CodePipeline ist der orchestrierende Service, der die einzelnen Schritte einer Deployment-Pipeline verbindet. Es definiert den Workflow von der Quellcode-Änderung bis zum Deployment.

AWS CodeBuild

CodeBuild ist ein vollständig verwalteter Build-Service. Er kompiliert den Quellcode, führt Tests aus und erzeugt deploybare Artefakte.

AWS CodeDeploy

CodeDeploy automatisiert das Deployment auf EC2-Instanzen, Lambda-Funktionen oder ECS-Services.

Pipeline-Architektur

Eine typische Pipeline besteht aus folgenden Stages:

Source → Build → Test → Deploy (Staging) → Deploy (Production)

Schritt 1: Source Stage einrichten

Die Source Stage überwacht das Code-Repository auf Änderungen. AWS unterstützt verschiedene Quellen:

  • AWS CodeCommit - AWS-eigener Git-Service
  • GitHub - Über GitHub Connections
  • Bitbucket - Über Bitbucket Connections
  • S3 - Für Artefakt-basierte Deployments

Beispiel: GitHub Connection

# cloudformation-template.yaml
SourceStage:
  Actions:
    - Name: Source
      ActionTypeId:
        Category: Source
        Owner: AWS
        Provider: CodeStarSourceConnection
        Version: 1
      Configuration:
        ConnectionArn: !Ref GitHubConnection
        FullRepositoryId: myorg/myrepo
        BranchName: main
      OutputArtifacts:
        - Name: SourceCode

Schritt 2: Build Stage mit CodeBuild

buildspec.yml für Scala/sbt

version: 0.2

phases:
  install:
    runtime-versions:
      java: corretto11
  pre_build:
    commands:
      - echo "Installing sbt..."
      - curl -fL "https://github.com/sbt/sbt/releases/download/v1.9.0/sbt-1.9.0.tgz" | tar xz
      - export PATH="$PATH:./sbt/bin"
  build:
    commands:
      - echo "Building..."
      - sbt clean compile
      - sbt test
      - sbt "Docker / stage"
  post_build:
    commands:
      - echo "Build completed"
      - docker build -t $ECR_REPO:$CODEBUILD_RESOLVED_SOURCE_VERSION .
      - docker push $ECR_REPO:$CODEBUILD_RESOLVED_SOURCE_VERSION

artifacts:
  files:
    - appspec.yml
    - taskdef.json
  discard-paths: no

cache:
  paths:
    - '/root/.ivy2/**/*'
    - '/root/.sbt/**/*'

CodeBuild Projekt erstellen

BuildProject:
  Type: AWS::CodeBuild::Project
  Properties:
    Name: my-scala-build
    ServiceRole: !GetAtt CodeBuildRole.Arn
    Artifacts:
      Type: CODEPIPELINE
    Environment:
      Type: LINUX_CONTAINER
      ComputeType: BUILD_GENERAL1_MEDIUM
      Image: aws/codebuild/amazonlinux2-x86_64-standard:4.0
      PrivilegedMode: true
      EnvironmentVariables:
        - Name: ECR_REPO
          Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/my-app
    Source:
      Type: CODEPIPELINE
      BuildSpec: buildspec.yml
    Cache:
      Type: S3
      Location: !Sub ${CacheBucket}/build-cache

Schritt 3: Deploy Stage

Option A: ECS Deployment

Für containerisierte Anwendungen ist ECS eine gute Wahl:

DeployStage:
  Actions:
    - Name: Deploy
      ActionTypeId:
        Category: Deploy
        Owner: AWS
        Provider: ECS
        Version: 1
      Configuration:
        ClusterName: !Ref ECSCluster
        ServiceName: !Ref ECSService
        FileName: imagedefinitions.json
      InputArtifacts:
        - Name: BuildOutput

Option B: Lambda Deployment

Für Serverless-Anwendungen:

DeployStage:
  Actions:
    - Name: Deploy
      ActionTypeId:
        Category: Deploy
        Owner: AWS
        Provider: CloudFormation
        Version: 1
      Configuration:
        ActionMode: CREATE_UPDATE
        StackName: my-lambda-stack
        TemplatePath: BuildOutput::template.yaml

Schritt 4: Approval Stage (optional)

Für Production-Deployments empfiehlt sich eine manuelle Freigabe:

ApprovalStage:
  Actions:
    - Name: ManualApproval
      ActionTypeId:
        Category: Approval
        Owner: AWS
        Provider: Manual
        Version: 1
      Configuration:
        NotificationArn: !Ref ApprovalTopic
        CustomData: "Bitte Deployment auf Production freigeben"

Komplette Pipeline

Pipeline:
  Type: AWS::CodePipeline::Pipeline
  Properties:
    Name: my-scala-pipeline
    RoleArn: !GetAtt PipelineRole.Arn
    Stages:
      - Name: Source
        Actions:
          - Name: Source
            # ... Source Configuration
      - Name: Build
        Actions:
          - Name: Build
            # ... Build Configuration
      - Name: DeployStaging
        Actions:
          - Name: Deploy
            # ... Staging Deployment
      - Name: Approval
        Actions:
          - Name: ManualApproval
            # ... Approval Configuration
      - Name: DeployProduction
        Actions:
          - Name: Deploy
            # ... Production Deployment

Best Practices

1. Infrastructure as Code

Die gesamte Pipeline sollte als CloudFormation oder CDK definiert werden. So ist sie versioniert und reproduzierbar.

2. Secrets Management

Verwenden Sie AWS Secrets Manager oder Parameter Store für Credentials:

EnvironmentVariables:
  - Name: DB_PASSWORD
    Type: SECRETS_MANAGER
    Value: my-secret-name:password

3. Caching nutzen

CodeBuild-Caching beschleunigt Builds erheblich - besonders für sbt mit seinen vielen Dependencies.

4. Notifications einrichten

SNS-Benachrichtigungen bei Build-Fehlern:

NotificationRule:
  Type: AWS::CodeStarNotifications::NotificationRule
  Properties:
    Name: pipeline-notifications
    Resource: !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${Pipeline}
    EventTypeIds:
      - codepipeline-pipeline-pipeline-execution-failed
    Targets:
      - TargetType: SNS
        TargetAddress: !Ref NotificationTopic

Fazit

AWS CodePipeline bietet eine vollständige CI/CD-Lösung, die sich nahtlos in das AWS-Ökosystem integriert. Für Teams, die bereits auf AWS setzen, ist es eine natürliche Wahl. Die Kombination aus CodePipeline, CodeBuild und den verschiedenen Deployment-Optionen ermöglicht flexible und robuste Deployment-Workflows.

Bei innFactory nutzen wir AWS CodePipeline erfolgreich für unsere Cloud-Projekte und unterstützen Unternehmen dabei, ihre CI/CD-Prozesse auf AWS zu optimieren.

Tobias Jonas
Geschrieben von Tobias Jonas CEO & Gründer

Cloud-Architekt und Experte für AWS, Google Cloud, Azure und STACKIT. Vor der Gründung der innFactory bei Siemens und BMW tätig.

LinkedIn