Skip to content
developpushbuilddeploypush 하면 개발 서버까지 알아서

Building CI/CD for Autowini's Frontend on Bitbucket, Part 1

3 min readWorkMoved from my Tistory blogRead the Korean original

Project background and motivation

Autowini has several frontend projects that we separated out and improved in React.

The main ones are web-www-front (Autowini web), web-mobile-front (mobile web), and web-admin-front (admin pages).
We had been moving the existing JSP pages to React and improving them one at a time, starting with the pages that had the most visitors and the most frequent issues.

These separated React pages are served from build output uploaded to an IDC (internet data center) server. Until then, once development was done, we merged into the develop branch and uploaded the build files to the IDC directly from the CLI.

That works if only one person is developing. But if my senior colleague covered for me while I was on vacation, or a new frontend developer joined, I thought uploading files to the IDC by hand from the CLI could cause confusion and problems.

For example, if someone uploads build files to the IDC from their working branch before merging into develop, what the dev server shows can stop matching the actual code in the develop branch.

To fix this at the root, I decided to build a stable, consistent CI/CD pipeline.

First attempt and the problem

With help from GitHub Copilot, I created a bitbucket-pipelines.yml file and wrote the pipeline below. (For security, I masked sensitive information such as the IP address, username, and password variable names. In a real pipeline setup, keep these in separate environment variables.)

yaml
# Autowini Frontend Pipeline Configuration
# Use the Node.js 20 image (matches the project requirements)
image: node:20

definitions:
  caches:
    pnpm: ~/.pnpm-store

pipelines:
  branches:
    develop:
      - step:
          name: 'Build and Deploy to Dev Server'
          caches:
            - pnpm
          script:
            # Install pnpm
            - npm install -g pnpm@10.6.3

            # Install dependencies
            - pnpm install

            # Build for the dev server
            - pnpm build:dev

            # Install sshpass (for password authentication)
            - apt-get update && apt-get install -y sshpass

            # Add the server to SSH known_hosts
            - mkdir -p ~/.ssh
            - ssh-keyscan -H $DEPLOY_SERVER_IP >> ~/.ssh/known_hosts 2>/dev/null

            # Upload files via SCP (password authentication)
            # SSH_PASSWORD must be set in Repository Settings > Pipelines > Repository variables
            - sshpass -p "$SSH_PASSWORD" scp -r dist/* $DEPLOY_USER@$DEPLOY_SERVER_IP:$DEPLOY_TARGET_PATH
          artifacts:
            - dist/**
  • I wrote a script that builds on the develop branch and sends the build output to the IDC server with scp.
  • I set the SSH password (SSH_PASSWORD) as a repository variable and connected with password authentication.

The problem was that the Bitbucket Pipelines IPs were not allowed through the IDC firewall, so the connection kept timing out.

Analyzing the problem and working toward a fix

Following the official Bitbucket docs (https://support.atlassian.com/bitbucket-cloud/docs/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall/), I checked the IPv4 inbound IP lists for bitbucket.org, api.bitbucket.org, and altssh.bitbucket.org. I passed them to my team lead, and we asked Megazone IDC, our partner company, to allow them through the firewall.

But when I reran the pipeline, the same error kept happening.

To debug from inside the pipeline, I printed the outbound IP the pipeline's runtime environment was actually using, and got the following.

text
52.90.48.7
52.0.3.221
44.208.32.148
...

These IPs were not on the allow list, and when I looked them up, they turned out to be in AWS EC2 ranges. Bitbucket Pipelines runs on AWS infrastructure managed by Atlassian, so the runtime environment that runs the pipeline also uses AWS EC2 IPs. That is why the output showed various public IPs assigned by AWS instead of one fixed IP. I also realized that this setup makes it hard to control access with an IDC firewall that only allows specific IPs.

(EC2 IPs for reference: https://ip-ranges.amazonaws.com/ip-ranges.json)

Internal discussion and contacting Bitbucket support

I talked it over with the backend developer who handles our internal infrastructure. We concluded that allowing the entire AWS IP range through the firewall was not appropriate for security and would also be inefficient to manage. So we also started looking at an alternative: run CI in Bitbucket Pipelines and handle CD in an internal system such as Jenkins.

Around then, another backend developer suggested I contact Bitbucket officially. I did, and got the following important answer from Bitbucket AI.

Key points for SSH connections from Bitbucket Pipelines

  • Pipeline steps that need SSH access must be set to at least size: 4x.
  • The runtime.cloud.atlassian-ip-ranges: true option must be enabled.
yaml
pipelines:
  default:
    - step:
        size: 4x4x # apply step size 4x
        runtime:
          cloud:
            atlassian-ip-ranges: true # use Atlassian's fixed IPs
        script:
          - <rest unchanged>
  • With this, Bitbucket Pipelines uses a fixed IP pool managed by Atlassian, so it can connect reliably even through the IDC firewall.

Conclusion and thoughts

To connect over SSH reliably from Bitbucket Pipelines, setting size: 4x or higher in the bitbucket-pipelines.yml file and enabling the atlassian-ip-ranges option were essential. After I applied these settings and we allowed Atlassian's fixed IPs through the IDC firewall, the SSH timeouts I had been getting were completely resolved, and we could run the CI/CD pipeline reliably.

I had spent a day on this before, and almost all of yesterday too, looking for the cause, and it did not come easily. Just as I was about to send an inquiry to the Bitbucket team as a last attempt, Bitbucket AI told me the key to the fix, and thanks to that I solved it quickly. This pipeline made our version control and deployment process more systematic, and I think it will be a big help to the whole team going forward.

  • #Atlassian
  • #Atlassian IP
  • #atlassian-ip-ranges
  • #Autowini
  • #Bitbucket
  • #bitbucket-pipelines.yml
  • #CI/CD pipeline
  • #IDC firewall

More in Work