labunix's blog

labunixのラボUnix

AWS CodeCommitをAWS CLIから設定してみる。

■AWS CodeCommitをAWS CLIから設定してみる。
 CodeCommitはリージョンサービス。

 アクセス許可は今回AWS CLIの対象外なので、
 予め「AWSCodeCommitFullAccess」をマネージメントコンソールでIAMユーザに割り当てておく。

 ルートアカウントのユーザーは制限があるので、IAMユーザを使用することにする。

 AWS CodeCommit の認証とアクセスコントロール
 https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/auth-and-access-control.html

■CodeCommitのポリシーは3種類

$ ./aws-policy-search codecommit
AWSCodeCommitPowerUser
AWSCodeCommitFullAccess
AWSCodeCommitReadOnly

■手動で実行している限りは無料枠を超過しそうにない、プライベートリポジトリ。

 AWS CodeCommit の料金
 https://aws.amazon.com/jp/codecommit/pricing/

■HTTPS/開発ツール/SSH接続を選択する。
 HTTPS接続の際には、AWS CLIのCredential Helper機能で
 AWS側の認証を行う必要があるので、今回は対象外とする。

 AWS CLI 認証情報ヘルパーを使用して Linux, macOS, or Unix で
  AWS CodeCommit リポジトリへの HTTPS 接続をセットアップする手順
 https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-https-unixes.html

 また、AWS Cloud9、Visual Studio、Eclipseと統合する要件は無いので今回はスルーする。

 Git 認証情報を使用して開発ツールから接続を設定する
 https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-ide.html

 なお、SSH接続で一からセットアップする場合は以下の手順を参照する。

 Linux, macOS, or Unix で AWS CodeCommit リポジトリへの SSH 接続をセットアップする手順
 https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-ssh-unixes.html

■各AWS リージョンでCodeCommitフィンガープリントが異なる点に注意する。

 AWS CLI を使用していない SSH ユーザーの セットアップ
 https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-without-cli.html

■やることが2つしかないのに、GUIからだと面倒なので、AWS CLIを使えないか探してみる。
 「upload-ssh-public-key」と「list-ssh-public-keys」を使う。

$ aws iam help | awk '/ssh/{print $NF}'
delete-ssh-public-key
get-ssh-public-key
list-ssh-public-keys
update-ssh-public-key
upload-ssh-public-key

■「aws-ssh-codecommit-init」を作成。
 引数にIAMユーザ名を渡すと、AWS側に公開鍵をアップロードして、ローカル側にAWSに接続する設定を入れる。
 一応、「~/.ssh/${awsiamuser}-codecommit」形式の既存のssh鍵があればssh-keygenしないし、
 「SSHPublicKeyId」が空でない(=すでに登録されている)なら、公開鍵をアップロードしないし、「.ssh/config」にも追記しない。
 「.ssh/config」に手動で追加したり、別のIAMユーザを追加した場合は想定していないので、そこは実行後に確認して下さい。

$ wget https://raw.githubusercontent.com/labunix/aws/main/aws-ssh-codecommit-init
$ chmod +x aws-ssh-codecommit-init
$ cat aws-ssh-codecommit-init 
#!/bin/bash

list-ssh-public-keys-check() {
  aws iam list-ssh-public-keys --user-name ${awsiamuser} >/dev/null 2>&1
  if [ $? -eq 0 ];then
    line=$(aws iam list-ssh-public-keys --user-name ${awsiamuser} | jq -r '.SSHPublicKeys[].SSHPublicKeyId' | wc -l)
  else
    echo "Not permit access!"
    exit 1
  fi
}

if [ $# -lt 1 ];then
  echo "Usage: $0 [aws-iam-user-name]"
  exit 1
fi

awsiamuser=$1
awssshkey=~/.ssh/${awsiamuser}-codecommit

list-ssh-public-keys-check

# for no change check.
# exit 0

# Not Found Only Action
if [ ! -f "${awssshkey}.pub" ];then
  ssh-keygen -f ${awssshkey}
fi

# Not Found Only Action

list-ssh-public-keys-check

if [ ${line} -eq 0 ];then
  aws iam upload-ssh-public-key --user-name ${awsiamuser} --ssh-public-key-body "$(cat ${awssshkey}.pub)"
  sshpubkeyid=$(aws iam list-ssh-public-keys --user-name ${awsiamuser} |  jq -r '.SSHPublicKeys[].SSHPublicKeyId')

  echo "Host git-codecommit.*.amazonaws.com" >> ~/.ssh/config
  echo "  User ${sshpubkeyid}" >> ~/.ssh/config
  echo "  IdentityFile ${awssshkey}" >> ~/.ssh/config
  chmod 600 ~/.ssh/config
fi

list-ssh-public-keys-check
if [ ${line} -eq 1 ];then
  echo "ok"
fi

■以下のように実行

$ ./aws-ssh-codecommit-init 
Usage: ./aws-ssh-codecommit-init [aws-iam-user-name]

$ ./aws-ssh-codecommit-init labunix-admin
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/labunix/.ssh/labunix-admin-codecommit.
Your public key has been saved in /home/labunix/.ssh/labunix-admin-codecommit.pub.
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX labunix@XXXXXXX
The key's randomart image is:
+---[RSA 2048]----+
〜省略〜
+----[SHA256]-----+
{
    "SSHPublicKey": {
        "UserName": "labunix-admin",
        "SSHPublicKeyId": "XXXXXXXXXXXXXXXXXXXXX",
        "Fingerprint": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "SSHPublicKeyBody": "ssh-rsa X512X labunix@XXX",
        "Status": "Active",
        "UploadDate": "2021-01-06T11:01:02Z"
    }
}
ok
■「aws-ssh-codecommit-init」の実行結果を確認
 .ssh/configにcodecommitが追加されていて、ssh秘密鍵は600、公開鍵は666、SSHPublicKeyIdは空(0)ではなくなった。

$ cat .ssh/config  | ./myscripts/lsec codecommit | awk '{if($1 ~ /User/){print "User XXX"}else{print}}'
Host git-codecommit.*.amazonaws.com
User XXX
  IdentityFile /home/labunix/.ssh/labunix-admin-codecommit

$ ls -l /home/labunix/.ssh/labunix-admin-codecommit*
-rw------- 1 labunix labunix 1831  16 20:00 /home/labunix/.ssh/labunix-admin-codecommit
-rw-r--r-- 1 labunix labunix  402  16 20:00 /home/labunix/.ssh/labunix-admin-codecommit.pub

$ awsiamuser=labunix-admin; aws iam list-ssh-public-keys --user-name ${awsiamuser} | jq -r '.SSHPublicKeys[].SSHPublicKeyId' | wc -l
1

■aws codecommitのサブコマンドは以下。

$ aws codecommit help | awk 'BEGIN{a=0}{if($0 ~ /^A/){a=1;getline}}{if(a==1 && NF>1){print $NF}}' | column
batch-get-repositories			get-comments-for-compared-commit	merge-pull-request-by-fast-forward
create-branch				get-comments-for-pull-request		post-comment-for-compared-commit
create-commit				get-commit				post-comment-for-pull-request
create-pull-request			get-differences				post-comment-reply
create-repository			get-file				put-file
credential-helper			get-folder				put-repository-triggers
delete-branch				get-merge-conflicts			test-repository-triggers
delete-comment-content			get-pull-request			update-comment
delete-file				get-repository				update-default-branch
delete-repository			get-repository-triggers			update-pull-request-description
describe-pull-request-events		help					update-pull-request-status
get-blob				list-branches				update-pull-request-title
get-branch				list-pull-requests			update-repository-description
get-comment				list-repositories			update-repository-name

■リポジトリが無いので作ってみる。

$ aws codecommit list-repositories
{
    "repositories": []
}

$ aws codecommit create-repository help | awk '$1 ~ /aws/&&/MyDemoRepo/'
          aws codecommit create-repository --repository-name MyDemoRepo --repository-description "My demonstration repository"

{
    "repositoryMetadata": {
        "accountId": "XXXXXXXXXXXX",
        "repositoryId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
        "repositoryName": "MyDemoRepo",
        "repositoryDescription": "My demonstration repository",
        "lastModifiedDate": 1609932093.683,
        "creationDate": 1609932093.683,
        "cloneUrlHttp": "https://git-codecommit.us-east-2.amazonaws.com/v1/repos/MyDemoRepo",
        "cloneUrlSsh": "ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/MyDemoRepo",
        "Arn": "arn:aws:codecommit:us-east-2:XXXXXXXXXXXX:MyDemoRepo"
    }
}

$ aws codecommit list-repositories
{
    "repositories": [
        {
            "repositoryName": "MyDemoRepo",
            "repositoryId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
        }
    ]
}

■git cloneしてみる。

 AWS CodeCommit への SSH 接続のトラブルシューティング -> CodeCommit のパブリックフィンガープリント
 https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/troubleshooting-ssh.html

$ git clone ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/MyDemoRepo
Cloning into 'MyDemoRepo'...
The authenticity of host 'git-codecommit.us-east-2.amazonaws.com (52.95.20.253)' can't be established.
RSA key fingerprint is SHA256:3lBlW2g5xn/NA2Ck6dyeJIrQOWvn7n8UEs56fG6ZIzQ.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'git-codecommit.us-east-2.amazonaws.com,52.95.20.253' (RSA) to the list of known hosts.
warning: You appear to have cloned an empty repository.
$ find MyDemoRepo/
MyDemoRepo/
MyDemoRepo/.git
MyDemoRepo/.git/branches
MyDemoRepo/.git/refs
MyDemoRepo/.git/refs/heads
MyDemoRepo/.git/refs/tags
MyDemoRepo/.git/HEAD
MyDemoRepo/.git/config
MyDemoRepo/.git/description
MyDemoRepo/.git/info
MyDemoRepo/.git/info/exclude
MyDemoRepo/.git/objects
MyDemoRepo/.git/objects/pack
MyDemoRepo/.git/objects/info
MyDemoRepo/.git/hooks
MyDemoRepo/.git/hooks/pre-push.sample
MyDemoRepo/.git/hooks/pre-rebase.sample
MyDemoRepo/.git/hooks/post-update.sample
MyDemoRepo/.git/hooks/pre-applypatch.sample
MyDemoRepo/.git/hooks/applypatch-msg.sample
MyDemoRepo/.git/hooks/commit-msg.sample
MyDemoRepo/.git/hooks/pre-commit.sample
MyDemoRepo/.git/hooks/prepare-commit-msg.sample
MyDemoRepo/.git/hooks/update.sample
MyDemoRepo/.git/hooks/pre-receive.sample
MyDemoRepo/.git/hooks/fsmonitor-watchman.sample

■リージョンサービスであることの確認。
 無効なリージョン以前に、プロキシ接続できないところは、
 lambdaのリージョン確認のときにも無効なリージョンだったところなので気にしない。

$ w3m -cols 240 -dump "https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-regions-availability-zones.html" | \
  awk 'BEGIN{a=0} \
         {if($1 ~ /コード/&& $2 ~ /名前/){a=1}else{if($1 ~ /詳細/){a=0}}} \
         {if(a==1&& !/^$|lax-/){gsub("不要|必要|必須|利用不可|オプトインステータス|ローカルゾーン","",$0); \
           printf "%-18s%s%s%s\n",$1,$2,$3,$4}}' > aws-region.txt

$ awk '!/コード/{print "echo \042["$1"\042];aws codecommit list-repositories --region "$1" | jq -r \047.repositories[].repositoryName\047"}' \
    aws-region.txt | sh 2>&1 | awk '{if(/^An error occurred/){print "無効なリージョン"}else{if($0 !~ /^$/){print $0}}}'
[us-east-2]
MyDemoRepo
[us-east-1]
[us-west-1]
[us-west-2]
[af-south-1]
Failed to connect to proxy URL: "http://192.168.100.200:8080/"
[ap-east-1]
無効なリージョン
[ap-south-1]
[ap-northeast-3]
Failed to connect to proxy URL: "http://192.168.100.200:8080/"
[ap-northeast-2]
[ap-southeast-1]
[ap-southeast-2]
[ap-northeast-1]
[ca-central-1]
[eu-central-1]
[eu-west-1]
[eu-west-2]
[eu-south-1]
無効なリージョン
[eu-west-3]
[eu-north-1]
[me-south-1]
無効なリージョン
[sa-east-1]