Every team's Git history lives on a repository nobody actually works in. It has no files you can open and edit, just the raw version data, and that emptiness is the entire point. Day 21 was building that central hub, and pairing it with the AWS equivalent of a fixed address, an Elastic IP that stays put.
One Linux task, one AWS task. Set up a bare Git repository on a storage server, then launch an EC2 instance and give it an Elastic IP. The tasks come from the KodeKloud Engineer platform.
The bare Git repo: a hub with no working tree
sudo yum install -y git
sudo mkdir -p /opt/media.git
sudo git init --bare /opt/media.git
ls /opt/media.git
The --bare flag is the whole idea. A normal Git repo has two parts, your working files and the hidden .git folder tracking their history. A bare repo has only the second part, the history, with no working tree at all. That is why bare repos are named with a .git suffix and why you never edit inside one directly.
Why would you want a repo you cannot work in? Because it is the shared hub. Developers push to it and pull from it, but nobody commits inside it, so there is never a checked-out branch to collide with an incoming push. This is exactly what GitHub and GitLab host on their side, a bare repo you sync against. Running git init --bare yourself is a good way to see there is no magic to a remote repo, it is just a repo with the working files left off. Keep the one distinction straight: git init makes a normal repo with a working directory for local development, git init --bare makes the central one everyone shares.
EC2 with an Elastic IP: launch, allocate, associate
On AWS, the task was to launch an instance and give it a static public IP, scripted end to end. The nice part is how it strings the steps together with bash variables:
# Launch, then capture the instance ID once it is running
aws ec2 run-instances --image-id ami-xxxx --instance-type t2.micro \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=xfusion-ec2}]'
INSTANCE_ID=$(aws ec2 describe-instances \
--filters "Name=tag:Name,Values=xfusion-ec2" \
--query 'Reservations[*].Instances[*].InstanceId' --output text)
aws ec2 wait instance-running --instance-ids $INSTANCE_ID
# Allocate an Elastic IP, capture its allocation ID, then associate it
ALLOCATION_ID=$(aws ec2 allocate-address --domain vpc \
--query 'AllocationId' --output text)
aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOCATION_ID
Two habits worth stealing. Capturing each ID into a variable with $(...) turns the whole thing into a script instead of a copy-paste relay, so you never paste the wrong i-0abc halfway through. And aws ec2 wait instance-running blocks until the instance is genuinely up before you try to associate the address, so you are not racing the API. One reminder from Day 10, because it applies the moment you allocate: every public IPv4 address is billed now, attached or not, since AWS changed that in early 2024. An Elastic IP you allocate and forget still costs you, so release the ones you are not using.
Build the fixed point on purpose
Both tasks were about creating something stable for others to depend on. The bare repo is the fixed point a whole team's history hangs off. An Elastic IP is the fixed address that a service retains across restarts. Neither is glamorous, and both are the kind of quiet infrastructure everything else assumes is simply there.
So here is the Day 21 question. Would you rather build the stable centre deliberately and know exactly what depends on it, or let it emerge by accident and find out what breaks the day it moves?
Day 21 down. Seventy-nine to go.
Top comments (0)