Skip to main content
· AWS · 4 min read

Syncing Bitbucket to AWS CodeCommit via Pipeline: Full SSH Setup

When your team uses Bitbucket but some infrastructure needs CodeCommit (for private pipelines, VPC endpoint access, or AWS IAM-based access control), you need a sync. Rather than a third-party integration, a Bitbucket pipeline can handle it directly via SSH.

The Architecture

%%{ init: { 'look': 'handDrawn' } }%%
graph LR
    A[Developer<br/>laptop] -->|git push| B[Bitbucket<br/>main repo]
    B -->|pipeline trigger| C[Bitbucket<br/>CI runner]
    C -->|SSH push<br/>with SSH key| D[AWS CodeCommit<br/>mirror repo]
    
    E[AWS IAM<br/>SSH key registered] -->|authenticates| D
    F[AWS VPC<br/>private access] -->|used by| D
    
    C -->|base64 encoded<br/>SSH config| G[~/.ssh/config<br/>reconstructed]

The pipeline SSH key is stored in Bitbucket’s environment variables (base64 encoded), decoded at runtime, and used to push to CodeCommit. The SSH config points to CodeCommit’s regional endpoint.

Step 1: Generate an SSH Key in Bitbucket

  1. Go to Repository Settings → Pipelines → SSH Keys
  2. Click Generate Key — Bitbucket creates an RSA key pair
  3. The public key is displayed — copy it
  4. Add git-codecommit.*.amazonaws.com to Known Hosts

Step 2: Register the Key in AWS IAM

# Get the SSH public key from Bitbucket
# It looks like: ssh-rsa AAAAB3NzaC1yc2EAAA...

# Upload to IAM user
aws iam upload-ssh-public-key \
  --user-name your-iam-user \
  --ssh-public-key-body "ssh-rsa AAAAB3NzaC1yc2EAAA..."

The IAM user needs CodeCommit permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "codecommit:GitPush",
        "codecommit:GitPull"
      ],
      "Resource": "arn:aws:codecommit:eu-central-1:123456789012:*"
    }
  ]
}

Step 3: Create the SSH Config

Host git-codecommit.*.amazonaws.com
  Hostname git-codecommit.eu-central-1.amazonaws.com
  User APKAEIBAERJR2EXAMPLE
  IdentityFile ~/.ssh/id_rsa
  StrictHostKeyChecking no

The User field is the SSH Key ID from the IAM user’s uploaded key — not the username. You’ll find it in the IAM console under SSH public keys for CodeCommit.

Step 4: Base64-Encode and Store in Bitbucket

# Encode the SSH config
base64 ~/.ssh/config > config_b64.txt

# Store as Bitbucket Pipelines environment variable:
# CODECOMMIT_SSH_CONFIG=<the base64 string>

The base64 encoding preserves the config across pipeline runs (newlines are preserved).

Step 5: The Pipeline Definition

definitions:
  steps:
    - step: &sync-codecommit
        name: Sync to CodeCommit
        script:
          # Decode SSH config
          - echo $CODECOMMIT_SSH_CONFIG | base64 -d > ~/.ssh/config
          - chmod 600 ~/.ssh/config

          # Verify SSH works
          - ssh -o StrictHostKeyChecking=no git-codecommit.eu-central-1.amazonaws.com

          # Add CodeCommit as a remote
          - git remote add codecommit ssh://git-codecommit.eu-central-1.amazonaws.com/v1/repos/your-repo

          # Push to CodeCommit
          - git push codecommit $BITBUCKET_BRANCH --force

pipelines:
  default:
    - step: *sync-codecommit
  branches:
    main:
      - step: *sync-codecommit

--force is needed because CodeCommit’s history may diverge from Bitbucket’s (if you’re only syncing one direction).

How It Executes

%%{ init: { 'look': 'handDrawn' } }%%
graph TD
    A[git push to Bitbucket] --> B[Pipeline starts]
    B --> C[Decode CODECOMMIT_SSH_CONFIG<br/>→ ~/.ssh/config]
    C --> D[SSH config points to<br/>CodeCommit regional endpoint]
    D --> E[SSH connects to CodeCommit<br/>authenticated by IAM SSH key]
    E --> F[git push copies<br/>Bitbucket HEAD to CodeCommit]
    F --> G[CodeCommit repo updated<br/>same commit SHA]

Every push to Bitbucket automatically syncs to CodeCommit. The CodeCommit repo mirrors Bitbucket within seconds.

Use Cases for This Pattern

| Use Case | Why CodeCommit | |---|---|---| | AWS PrivateLink access | CodeCommit endpoints accessible from VPC without internet | | AWS IAM integration | Centralized access control via IAM policies | | Cross-account pipelines | CodeCommit in different AWS account | | Regulatory requirements | Data residency in specific AWS region |

Known Limitations

  • History is not synced — only the current HEAD is pushed. Past commits don’t exist in CodeCommit.
  • Tags are not synced — only branches.
  • No bi-directional sync — this is one-way (Bitbucket → CodeCommit).
  • SSH key rotation — if you rotate the SSH key in IAM, update the Bitbucket environment variable.

For teams that need a full bidirectional mirror with history, a dedicated replication tool (like AWS CodeStar or a custom Lambda) is more appropriate. This pipeline sync works for continuous delivery scenarios where CodeCommit is just a deployment target.