|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Prompt for user input |
| 4 | +read -p "Enter Docker image to pull (e.g., nginx:latest): " DOCKER_IMAGE |
| 5 | +read -p "Enter the name of the repository you'll be moving your image to: " ECR_REPO_NAME |
| 6 | +read -p "Enter the name of your EC2 key pair (do not include .pem): " KEY_NAME |
| 7 | + |
| 8 | +# Constants (customize as needed) |
| 9 | +AMI_ID="ami-0e58b56aa4d64231b" # Replace with valid Amazon Linux 2 AMI ID for your region |
| 10 | +INSTANCE_TYPE="t2.micro" |
| 11 | +SECURITY_GROUP_NAME="ec2-docker-sg" |
| 12 | +INSTANCE_PROFILE_NAME="EC2InstanceECRAccessProfile" |
| 13 | +REGION="us-east-1" |
| 14 | +VOLUME_SIZE=20 |
| 15 | +KEY_FILE="${KEY_NAME}.pem" |
| 16 | + |
| 17 | + |
| 18 | +echo "Looking up VPC ID..." |
| 19 | +VPC_ID=$(aws ec2 describe-vpcs \ |
| 20 | + --query "Vpcs[0].VpcId" \ |
| 21 | + --region "$REGION" \ |
| 22 | + --output text) |
| 23 | + |
| 24 | +echo "Creating security group..." |
| 25 | + |
| 26 | +CREATE_OUTPUT=$(aws ec2 create-security-group \ |
| 27 | + --group-name "$SECURITY_GROUP_NAME" \ |
| 28 | + --description "Allow SSH and internet access" \ |
| 29 | + --region "$REGION" \ |
| 30 | + --vpc-id "$VPC_ID" \ |
| 31 | + --output text --query 'GroupId' 2>&1) |
| 32 | + |
| 33 | +if [[ $? -ne 0 ]]; then |
| 34 | + if [[ "$CREATE_OUTPUT" == *"InvalidGroup.Duplicate"* ]]; then |
| 35 | + echo "Security group '$SECURITY_GROUP_NAME' already created." |
| 36 | + |
| 37 | + # Optionally retrieve the existing group ID |
| 38 | + SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \ |
| 39 | + --region "$REGION" \ |
| 40 | + --filters Name=group-name,Values="$SECURITY_GROUP_NAME" \ |
| 41 | + --query 'SecurityGroups[0].GroupId' \ |
| 42 | + --output text) |
| 43 | + else |
| 44 | + echo "Failed to create security group: $CREATE_OUTPUT" |
| 45 | + exit 1 |
| 46 | + fi |
| 47 | +else |
| 48 | + SECURITY_GROUP_ID="$CREATE_OUTPUT" |
| 49 | + echo "Security group created with ID: $SECURITY_GROUP_ID" |
| 50 | +fi |
| 51 | + |
| 52 | +echo "SECURITY_GROUP_ID: $SECURITY_GROUP_ID" |
| 53 | + |
| 54 | +MAX_RETRIES=5 |
| 55 | +RETRY_DELAY=5 #seconds |
| 56 | +ATTEMPT=1 |
| 57 | + |
| 58 | +echo "Authorizing security group ingress (SSH on port 22)..." |
| 59 | + |
| 60 | +while [[ $ATTEMPT -le $MAX_RETRIES ]]; do |
| 61 | + if aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID \ |
| 62 | + --protocol tcp --port 22 --cidr 0.0.0.0/0; then |
| 63 | + echo "Ingress rule added successfully." |
| 64 | + break |
| 65 | + else |
| 66 | + echo "Attempt $ATTEMPT failed. Retrying in $RETRY_DELAY seconds..." |
| 67 | + sleep $RETRY_DELAY |
| 68 | + ((ATTEMPT++)) |
| 69 | + fi |
| 70 | +done |
| 71 | + |
| 72 | +if [[ $ATTEMPT -gt $MAX_RETRIES ]]; then |
| 73 | + echo "Failed to authorize ingress after $MAX_RETRIES attempts." |
| 74 | + exit 1 |
| 75 | +fi |
| 76 | + |
| 77 | + |
| 78 | +# Create IAM role and instance profile |
| 79 | +echo "Setting up IAM role and instance profile..." |
| 80 | +aws iam create-role --role-name $INSTANCE_PROFILE_NAME \ |
| 81 | + --assume-role-policy-document file://<(cat <<EOF |
| 82 | +{ |
| 83 | + "Version": "2012-10-17", |
| 84 | + "Statement": [{ |
| 85 | + "Effect": "Allow", |
| 86 | + "Principal": { "Service": "ec2.amazonaws.com" }, |
| 87 | + "Action": "sts:AssumeRole" |
| 88 | + }] |
| 89 | +} |
| 90 | +EOF |
| 91 | +) || true |
| 92 | + |
| 93 | +aws iam attach-role-policy --role-name $INSTANCE_PROFILE_NAME \ |
| 94 | + --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess || true |
| 95 | + |
| 96 | +aws iam create-instance-profile --instance-profile-name $INSTANCE_PROFILE_NAME || true |
| 97 | +aws iam add-role-to-instance-profile \ |
| 98 | + --instance-profile-name $INSTANCE_PROFILE_NAME \ |
| 99 | + --role-name $INSTANCE_PROFILE_NAME || true |
| 100 | + |
| 101 | +echo "Waiting for IAM instance profile propagation..." |
| 102 | +sleep 5 |
| 103 | + |
| 104 | +echo "Creating key pair..." |
| 105 | + |
| 106 | +KEY_OUTPUT=$(aws ec2 create-key-pair \ |
| 107 | + --key-name "$KEY_NAME" \ |
| 108 | + --query 'KeyMaterial' \ |
| 109 | + --output text \ |
| 110 | + --region "$REGION" 2>&1) |
| 111 | + |
| 112 | +if [[ $? -ne 0 ]]; then |
| 113 | + if [[ "$KEY_OUTPUT" == *"InvalidKeyPair.Duplicate" ]]; then |
| 114 | + echo "Key pair '$KEYNAME' already created." |
| 115 | + exit 1 |
| 116 | + fi |
| 117 | +else |
| 118 | + echo "$KEY_OUTPUT" > "$KEY_FILE" |
| 119 | + chmod 400 "$KEY_FILE" |
| 120 | + echo "Key pair created and saved to $KEY_FILE" |
| 121 | +fi |
| 122 | + |
| 123 | +echo "Waiting for key propagation..." |
| 124 | +sleep 5 |
| 125 | + |
| 126 | +USER_SCRIPT=$(cat <<EOF |
| 127 | +#!/bin/bash |
| 128 | +set -e |
| 129 | +yum update -y |
| 130 | +amazon-linux-extras install docker -y |
| 131 | +service docker start |
| 132 | +usermod -a -G docker ec2-user |
| 133 | +
|
| 134 | +yum install -y unzip curl |
| 135 | +curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" |
| 136 | +unzip -q awscliv2.zip |
| 137 | +./aws/install |
| 138 | +
|
| 139 | +ACCOUNT_ID=\$(aws sts get-caller-identity --query "Account" --output text) |
| 140 | +aws ecr get-login-password --region "$REGION" | docker login --username AWS --password-stdin "\${ACCOUNT_ID}.dkr.ecr.$REGION.amazonaws.com" |
| 141 | +
|
| 142 | +aws ecr describe-repositories --repository-names "$ECR_REPO_NAME" --region "$REGION" >/dev/null 2>&1 || \ |
| 143 | +aws ecr create-repository --repository-name "$ECR_REPO_NAME" --region "$REGION" |
| 144 | +
|
| 145 | +docker pull "$DOCKER_IMAGE" |
| 146 | +IMAGE_URI="\${ACCOUNT_ID}.dkr.ecr.$REGION.amazonaws.com/$ECR_REPO_NAME" |
| 147 | +docker tag "$DOCKER_IMAGE" "\$IMAGE_URI" |
| 148 | +aws ecr get-login-password --region "$REGION" | docker login --username AWS --password-stdin "\${ACCOUNT_ID}.dkr.ecr.$REGION.amazonaws.com" |
| 149 | +docker push "\$IMAGE_URI" |
| 150 | +
|
| 151 | +echo "Docker maybe finished...?" |
| 152 | +EOF |
| 153 | +) |
| 154 | + |
| 155 | +# Launch EC2 instance |
| 156 | +echo "Launching EC2 instance..." |
| 157 | + |
| 158 | +INSTANCE_ID=$(aws ec2 run-instances \ |
| 159 | + --image-id "$AMI_ID" \ |
| 160 | + --count 1 \ |
| 161 | + --instance-type "$INSTANCE_TYPE" \ |
| 162 | + --key-name "$KEY_NAME" \ |
| 163 | + --security-group-ids "$SECURITY_GROUP_ID" \ |
| 164 | + --subnet-id "subnet-0ca1bb4bb3fce6c53" \ |
| 165 | + --block-device-mappings "[{\"DeviceName\":\"/dev/xvda\",\"Ebs\":{\"VolumeSize\":$VOLUME_SIZE}}]" \ |
| 166 | + --iam-instance-profile Name=$INSTANCE_PROFILE_NAME \ |
| 167 | + --associate-public-ip-address \ |
| 168 | + --region "$REGION" \ |
| 169 | + --user-data "$USER_SCRIPT" \ |
| 170 | + --query 'Instances[0].InstanceId' --output text) |
| 171 | + |
| 172 | +echo "EC2 Instance ID: $INSTANCE_ID" |
| 173 | + |
| 174 | +## Wait for the instance to be running |
| 175 | +aws ec2 wait instance-running --instance-ids "$INSTANCE_ID" |
| 176 | +PUBLIC_IP=$(aws ec2 describe-instances --instance-ids "$INSTANCE_ID" \ |
| 177 | + --query "Reservations[0].Instances[0].PublicIpAddress" --output text) |
| 178 | + |
| 179 | +echo "If you wish to login a pem key has been put in your working directory. The instance public IP is: $PUBLIC_IP" |
| 180 | +echo "It can take up to 15 minutes for an image to appear in your private repository." |
0 commit comments