Skip to main content

AWS EC2 - CLI: Manage EC2 Instances and Security Groups, Automate EC2 Configuration with Cloud-init

731 words·
AWS EC2 Security Group Cloud-init
Table of Contents

Prerequisites
#

Policies
#

Create a new IAM User and attach the following permission:
AmazonEC2FullAccess

Create an access key for the IAM user:
AWS Access Key ID: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY


Install AWS CLI
#

# Update packages
sudo apt update

# Unstall zip tool
sudo apt install unzip -y

# Download AWS CLI zip file
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

# Unzip
unzip awscliv2.zip

# Install
sudo ./aws/install

# Check version
/usr/local/bin/aws --version

AWS Configure
#

# Start AWS CLI configuration
aws configure

# Shell output:
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: eu-central-1
Default output format [None]:

AWS CLI
#

Launch EC2 Instance
#

aws ec2 run-instances \
    --image-id ami-04e601abe3e1a910f \
    --count 1 \
    --instance-type t2.micro \
    --key-name aws_private1 \
    --security-group-ids sg-0123456789abcdef0 \
    --user-data file://$HOME/cloud-init/cloud-init.txt

Explanation:

aws ec2 run-instances \
    --image-id ami-04e601abe3e1a910f \ # VM image
    --count 1 \ # Number of EC2 instances
    --instance-type t2.micro \ # Instance type
    --key-name aws_private1 \ # Existing SSH keypair
    --security-group-ids sg-0123456789abcdef0 \ # Existing security group
    --user-data file://$HOME/cloud-init/cloud-init.txt # Path to cloud-init file

Launch EC2 Instance (more options)
#

aws ec2 run-instances \
    --image-id ami-04e601abe3e1a910f \
    --count 1 \
    --instance-type t2.micro \
    --key-name aws_private1 \
    --security-group-ids sg-0123456789abcdef0 \
    --subnet-id subnet-0c19f580c157ebabb \
    --block-device-mappings "[{\"DeviceName\":\"/dev/sdb\",\"Ebs\":{\"VolumeSize\":8,\"DeleteOnTermination\":true}}]" \
    --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=EC2-Apache2}]' 'ResourceType=volume,Tags=[{Key=Name,Value=EC2-Apache-Disk}]' \
    --user-data file://$HOME/cloud-init/cloud-init.txt

Explanation:

aws ec2 run-instances \
    --image-id ami-04e601abe3e1a910f \ # VM image
    --count 1 \ # Number of EC2 instances
    --instance-type t2.micro \ # Instance type
    --key-name aws_private1 \ # Define (existing) SSH keypair
    --security-group-ids sg-0123456789abcdef0 \ # # Define (existing) security group
    --subnet-id subnet-0c19f580c157ebabb \ # Define VPC subnet
    --block-device-mappings "[{\"DeviceName\":\"/dev/sdb\",\"Ebs\":{\"VolumeSize\":8,\"DeleteOnTermination\":true}}]" \ # Add second disk
    --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=EC2-Apache2}]' 'ResourceType=volume,Tags=[{Key=Name,Value=EC2-Apache-Disk}]' \ # Define EC2 and second disk name
    --user-data file://$HOME/cloud-init/cloud-init.txt # Path to cloud-init file
# Shell output:
{
    "Groups": [],
    "Instances": [
        {
            "AmiLaunchIndex": 0,
            "ImageId": "ami-04e601abe3e1a910f",
            "InstanceId": "i-03b77bad7e414fbb6", # Instance ID
            "InstanceType": "t2.micro",
            "KeyName": "aws_ssh-1",
            "LaunchTime": "2023-09-13T19:46:01+00:00",
...

Start, Stop… EC2 Instance
#

# Rename Instance / Define Instance Name
aws ec2 create-tags --resources i-03b77bad7e414fbb6 --tags Key=Name,Value=Apache2

# Stop Instance
aws ec2 stop-instances --instance-ids i-03b77bad7e414fbb6

# Start Instance
aws ec2 start-instances --instance-ids i-03b77bad7e414fbb6

# Terminate Instance
aws ec2 terminate-instances --instance-ids i-03b77bad7e414fbb6

EC2 Security Groups
#

Note: Find default VPC ID under https://console.aws.amazon.com/vpc/

Create SG
#

# Create AWS EC2 security group
aws ec2 create-security-group --group-name apache2 --description "webserver" --vpc-id vpc-0123456789abcdef0 --region eu-central-1

# Shell output:
{
    "GroupId": "sg-0c64370bb74120968"
}

List SGs
#

# List AWS EC2 security groups
aws ec2 describe-security-groups --region eu-central-1 --query 'SecurityGroups[*].[GroupId,VpcId,GroupName]' --output table

# Shell output:
--------------------------------------------------------------
|                   DescribeSecurityGroups                   |
+-----------------------+-------------------------+----------+
|  sg-0809d50a7af66a144 |  vpc-0123456789abcdef0  |  default |
|  sg-0c64370bb74120968 |  vpc-0a1b2c3d4e5f67890  |  apache2 |
+-----------------------+-------------------------+----------+

Delete SG
#

# Delete AWS EC2 security group: Define by ID
aws ec2 delete-security-group --group-id sg-0c64370bb74120968 --region eu-central-1

# Delete AWS EC2 security group: Define by name
aws ec2 delete-security-group --group-name apache2 --region eu-central-1

Create SG Inbound Rule
#

# Create Inbound rule for security group
aws ec2 authorize-security-group-ingress --group-id sg-0c64370bb74120968 --protocol tcp --port 80 --cidr 0.0.0.0/0

# Shell output:
{
    "Return": true,
    "SecurityGroupRules": [
        {
            "SecurityGroupRuleId": "sgr-059149d4471431500",
            "GroupId": "sg-0c64370bb74120968",
            "GroupOwnerId": "123456789012",
            "IsEgress": false,
            "IpProtocol": "tcp",
            "FromPort": 80,
            "ToPort": 80,
            "CidrIpv4": "0.0.0.0/0"
        }
    ]
}

Revoke SG Inbound Rule
#

aws ec2 revoke-security-group-ingress --group-id sg-0c64370bb74120968 --protocol tcp --port 80 --cidr 0.0.0.0/0

# Shell Output:
{
    "Return": true
}

List SG Rules
#

# List inbound & outbound rules: Define by SG ID
aws ec2 describe-security-groups --group-ids sg-0c64370bb74120968 --region eu-central-1

# List inbound & outbound rules: Define by SG name
aws ec2 describe-security-groups --group-names apache2 --region eu-central-1


# List only inbound rules
aws ec2 describe-security-groups --group-ids sg-0c64370bb74120968 --region eu-central-1 --query 'SecurityGroups[].IpPermissions[]'

# List only outbound rules
aws ec2 describe-security-groups --group-ids sg-0c64370bb74120968 --region eu-central-1 --query 'SecurityGroups[].IpPermissionsEgress[]'

Cloud-init (Ubuntu)
#

# Set permissions
chmod 600 ~/cloud-init/cloud-init.txt
# Cloud-init log path
/var/log/cloud-init.log
/var/log/cloud-init-output.log 

Install Package
#

#cloud-config
package_update: true
package_upgrade: true

packages:
  - apache2

runcmd:
  - systemctl start apache2
  - sudo systemctl enable apache2
  - echo "Apache2 test." > /var/www/html/index.html

Create User
#

users:
  - default
  - name: user1
    groups: [ sudo ]
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    shell: /bin/bash
    ssh-authorized-keys: 
    - ssh-rsa AAAAB3NzaC...

Explanation:

users:
  - default # Create default user (distribution specific, ob Ubuntu it's ubuntu)
  - name: user1 # Create custom user
    groups: [ sudo ] # Add user to groups
    sudo: "ALL=(ALL) NOPASSWD:ALL" # No sudo PW
    shell: /bin/bash # Define shell
    ssh-authorized-keys: # Define public SSH keys
    - ssh-rsa AAAAB3NzaC...