일반적으로 Git에서 하나의 repository 에 하나의 origin remote repository 를 연결해서 사용한다. 그런데 만약 하나의 repository 에서 브랜치별로 다른 remote repository 에 연결해서 쓰고 싶을 땐 어떻게 해야 될까? 그것도 두 remote repository 가 서로 다른 인증정보를 필요로 하는 private repository 일 경우에 말이다.
예를 들어 보자.
EXAMPLE 이라는 하나의 local repository 가 있다. 이 repository 에는 master 브랜치와 release 브랜치가 있다.
그리고 A, B 두 개의 AWS 계정이 있다. 첫 번째 A 계정에는 DEV 라는 CodeCommit repository 가 있다. 두 번째 B 계정에는 PROD 라는 CodeCommit repository 가 있다. (CodeCommit은 AWS에서 제공하는 VCS 이다.)
여기서 master 브랜치는 A 계정의 DEV repository에 push 해야 한다. 그리고 release 브랜치는 B 계정의 PROD repository에 push 해야 한다. (보안강화를 위해 이런 행동을 한다고 가정한다.)
두 AWS 계정은 당연히 서로 다른 인증정보를 필요로 한다.
이럴 때 어떻게 하면 될까? 평소대로 하면 될까? (그러면 내가 글을 안썼겠지...)
다른 개발자분들은 어떨지 모르겠지만, 난 평소에 HTTPS 프로토콜로 Git 작업을 한다. 이유는 편해서? SSH는 해본 적도 없었고 HTTPS로 잘만 되어 왔기 때문에 굳이 SSH를 할 필요가 없었다.
근데 내가 하나의 컴퓨터에서 2개의 private Git 계정에 붙어 본 적이 있었던가...? 생각해보면 없었다.
왜냐하면 macOS 는 HTTPS의 경우 git-credential-osxkeychain 방식으로 Git 정보를 저장해놓는데, 요 놈이 하나의 서비스에 하나의 계정정보밖에 못 저장한다. AWS CodeCommit의 경우를 예를 들면, 같은 리젼의 CodeCommit은 하나의 HTTPS credential 밖에 저장할 수 없다. "키체인 접근" 앱을 켜서 검색창에 git 을 검색해보면 직접 확인해볼 수 있다. 만약 다른 계정을 등록하려고 하면 등록이 안된다.
나의 경우 "키체인 접근" 앱에 들어가서 데이터를 삭제한 다음 등록을 시도해서 암호를 입력해야 했다. 이렇게 하려면 계속 암호를 어딘가에 들고 있어야 하고 (랜덤생성암호일 경우) 일단 졸라 귀찮고 불편하다..
하지만 SSH 프로토콜은 두 계정의 인증정보를 가지는 것이 가능하다. SSH 키를 생성해서 각각 등록절차를 거친다면 가능하다.
지금부터 SSH 프로토콜을 이용해서 두 개의 private remote repository 에 push 해보자!
위의 예시대로 진행해보겠다.
ssh-keygen
명령어로 SSH key 를 생성한다.~/.ssh/config
파일에 IAM에서 생성된 SSH 키 ID 를 등록한다.SSH key를 다음과 같이 DEV 용과 PROD 용 2개 만든다.
1$ ssh-keygen -t rsa -C "dev@example.com"2Generating public/private rsa key pair.3Enter file in which to save the key (/Users/username/.ssh/id_rsa): /Users/username/.ssh/id_rsa_dev_example4Enter passphrase (empty for no passphrase):5Enter same passphrase again:6Your identification has been saved in /Users/username/.ssh/id_rsa_dev_example.7Your public key has been saved in /Users/username/.ssh/id_rsa_dev_example.pub.8The key fingerprint is:9SHA256:sSx73L2zJo4noY1avG0uNSY2E7Mfds2eE//pUg9NEV0 dev@example.com10The key's randomart image is:11+---[RSA 2048]----+12| .E|13| ..|14| . .|15| o. o .|16| .+S o o |17| .*+B...+ ...|18| .+%o=...+...|19| .++=.o *o. o|20| ...+++.oo+o+.|21+----[SHA256]-----+2223$ ssh-keygen -t rsa -C "prod@example.com"24Generating public/private rsa key pair.25Enter file in which to save the key (/Users/username/.ssh/id_rsa): /Users/username/.ssh/id_rsa_prod_example26Enter passphrase (empty for no passphrase):27Enter same passphrase again:28Your identification has been saved in /Users/username/.ssh/id_rsa_prod_example.29Your public key has been saved in /Users/username/.ssh/id_rsa_prod_example.pub.30The key fingerprint is:31SHA256:y0hFMdb5RGp86DoWJipvKUj0UHYDsDdsPw48aKGmVCo prod@example.com32The key's randomart image is:33+---[RSA 2048]----+34| .... =o o. |35| oo o o ooo. |36| oo*. . . =o. |37|.oO o . o .. |38|E*o+ oo S . |39|*. .+o.= + |40|o.. .o. * |41|. .oo . . |42| o. |43+----[SHA256]-----+
~/.ssh
에 2개의 SSH 키를 만들었다.
[filename].pub
파일이 public 키 이며,
[filename]
파일이 private 키 이다.
확인해보자!
1$ cd ~/.ssh2$ l3total 04drwx------ 13 username staff 416B 6 24 11:02 .5drwxr-xr-x+ 39 username staff 1.2K 6 24 11:04 ..6-rw-r--r-- 1 username staff 342B 6 24 01:26 config7-rw------- 1 username staff 1.6K 6 24 11:02 id_rsa_dev_example // private 키8-rw-r--r-- 1 username staff 397B 6 24 11:02 id_rsa_dev_example.pub // public 키9-rw------- 1 username staff 1.6K 6 24 11:02 id_rsa_prod_example // private 키10-rw-r--r-- 1 username staff 398B 6 24 11:02 id_rsa_prod_example.pub // public 키11-rw-r--r-- 1 username staff 2.3K 6 24 01:13 known_hosts
생성된 public key 는 다음과 같다.
1$ cat id_rsa_dev_example.pub2ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzpasQc4lsML8NRAaEqi8WLIxjlkG4SYvE2C4IUdHjpEGOY/4JNlmNkLFapkxZVgMq1P/49qjm/Je1nwOGG+mEKXhPZVP3+NVdla/jCbZvLeWoADGJ5TseJnBIwjCUlN3oZpIhrT+vOj7+xjpmGeFpkC66VPWTQ+nANwdvUcGJp4xku2oxABdGKs4veMhsQKOG4t6mCvc9sXfUVaiJ/im+TCBUsrf2xyhURlwZpPSodzKZlsbMRBU7trKbwdV8go/bQZQwzCTTtc2TfM6yoo92c9sfaMbtGenW7slTqL+foztFuyweYIj74HQJkfLSZaQ02AddDv6gBcWvxby07NYX dev@example.com3$ cat id_rsa_prod_example.pub4ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDb5nuzqawJvFKuTJa48j0EpsMYrBAAadHA1hL/K+Yj2WzFcnBSsYV87SOC5OTl53Gc93hRe34eUaVbbkjtLQt0sYda+d2S195BMaPNEd03ZOlqdo5wHVPmj6W9hYyNQfYJ2CrzLXsq3ASmSFh5Upaz/ZVS3tvz7Az9vBJVD73iS3bJBsJlYtAwFrBWBx1TK4mgoGJnp4N+jCeZiY4clIxdyPTMO0/0hJqYELh7pWE0GDH8C+l013zQtVj7QvkHZfYlYplqsg5fF0/7vKJU7rneyhueihiELSJ4sMhkUJS0y38oss6GX431REvuN+2MJ4swcrdAMjHiUlDnH69uh+M5 prod@example.com
자 이제 성공적으로 SSH키를 생성했으니, public key 를 AWS IAM에 등록해야 한다.
id_rsa_dev_example.pub
public 키를 AWS 계정 "A" 의 IAM에 등록한다.id_rsa_prod_example.pub
public 키를 AWS 계정 "B" 의 IAM에 등록한다.~/.ssh/config
파일을 수정한다. ~/.ssh/config
파일이 없으면 생성한 후 수정한다.1$ vi ~/.ssh/config23Host dev-test // Host는 본인이 정하고 싶은 값으로 설정할 수 있다.4Hostname git-codecommit.ap-northeast-2.amazonaws.com // Hostname 은 리젼이 명시된 git-codecommit 주소어야 한다. "*" 는 안된다.5User A1B2C3D4 // IAM 에 등록한 SSH 키 ID (아까 메모장에 복사해 놓은 ID)6IdentityFile ~/.ssh/id_rsa_dev_example // IAM 에 등록한 SSH 키 ID 와 매핑되는 private key 위치 78Host prod-test // Host는 본인이 정하고 싶은 값으로 설정할 수 있다.9Hostname git-codecommit.ap-northeast-2.amazonaws.com // Hostname 은 리젼이 명시된 git-codecommit 주소어야 한다. "*" 는 안된다.10User D4C3B2A1 // IAM 에 등록한 SSH 키 ID (아까 메모장에 복사해 놓은 ID)11IdentityFile ~/.ssh/id_rsa_prod_example // IAM 에 등록한 SSH 키 ID 와 매핑되는 private key 위치
1$ cd ~/EXAMPLE // 기본적인 Git local repository 라고 가정한다.23$ git remote add dev ssh://dev-test/v1/repos/dev-multiple-remote-test // AWS "A" 계정의 "DEV" CodeCommit url4$ git remote add prod ssh://prod-test/v1/repos/prod-multiple-remote-test // AWS "B" 계정의 "PROD" CodeCommit url5$ git remote -v // 잘 설정되었는지 확인
git push [remote명] [로컬브랜치명]
으로 push 를 한다.1$ git push dev master // master 브랜치를 AWS "A" 계정의 "DEV" CodeCommit repository에 push 한다.2$ git push prod release // release 브랜치를 AWS "B" 계정의 "PROD" CodeCommit repository에 push 한다.
SourceTree, GitKraken 같은 클라이언트에서도 지원할 것 같은데 확인해보지는 않았다.. ㅋㅋ