Création d’une instance EC2 avec aws cli.
Une installation du programme aws-cli
(Installation de l’AWS CLI), sa configuration (Configuration de l’AWS CLI) et le paramétrage des variables d’environnement sont des pré-requis.
pip install boto boto3 awscli --upgrade --user
export ANSIBLE_HOST_KEY_CHECKING=False
export ANSIBLE_HOST_KEY_CHECKING=False >> ~/.profile
echo "export AWS_ACCESS_KEY_ID="AKIA2VVIC6KHZOMRV3XX"" >> .profile
echo "export AWS_SECRET_ACCESS_KEY="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"" >> .profile
echo "export AWS_DEFAULT_REGION="eu-west-1"" >> .profile
ssh-keygen -b 4096 -t rsa -f /tmp/sshkey -q -N ""
aws configure
cat ~/.aws/*
aws ec2 describe-instances
Pour lancer une instance EC2, il est nécessaire de disposer de quelques ressource préalable :
Une Amazon Machine Image (AMI) fournit les informations requises pour lancer une instance, qui est un serveur virtuel dans le cloud. Vous devez spécifier une AMI source lorsque vous lancez une instance. Lorsque vous avez besoin de plusieurs instances configurées de manière identique, il est possible de lancer plusieurs instances à partir d’une même AMI. Lorsque vous avez besoin d’instances configurées de manière différente, vous pouvez utiliser différentes AMI pour lancer ces instances.
Une AMI comprend les éléments suivants :
Un “mappage” de périphérique de stockage en mode bloc qui spécifie les volumes à attacher à l’instance lorsqu’elle est lancée
https://docs.aws.amazon.com/fr_fr/AWSEC2/latest/UserGuide/AMIs.html
Cette commande effectue une recherche d’une AMI Linux Amazon (Amazon Linux AMI) pour une instance “x86_64 HVM GP2” :
aws ec2 describe-images --filters "Name=description,Values=Amazon Linux AMI * x86_64 HVM GP2" --query 'Images[*].[CreationDate, Description, ImageId]' --output text | sort -k 1 | tail
2018-01-03T19:01:53.000Z Amazon Linux AMI 2017.09.1.20180103 x86_64 HVM GP2 ami-8715a2fa
2018-01-08T18:42:47.000Z Amazon Linux AMI 2017.09.1.20180108 x86_64 HVM GP2 ami-fe03b483
2018-01-15T19:12:53.000Z Amazon Linux AMI 2017.09.1.20180115 x86_64 HVM GP2 ami-8ee056f3
2018-01-18T23:08:21.000Z Amazon Linux AMI 2017.09.1.20171120 x86_64 HVM GP2 ami-27e85e5a
2018-03-07T06:59:00.000Z Amazon Linux AMI 2017.09.1-testlongids.20180307 x86_64 HVM GP2 ami-08f0e11237ddeb2f0
2018-03-07T06:59:52.000Z Amazon Linux AMI 2017.09.1.20180307 x86_64 HVM GP2 ami-4f55e332
2018-04-13T00:25:52.000Z Amazon Linux AMI 2018.03.0.20180412 x86_64 HVM GP2 ami-cae150b7
2018-05-08T18:10:54.000Z Amazon Linux AMI 2018.03.0.20180508 x86_64 HVM GP2 ami-969c2deb
2018-06-22T22:24:50.000Z Amazon Linux AMI 2018.03.0.20180622 x86_64 HVM GP2 ami-d50bbaa8
2018-08-11T02:29:44.000Z Amazon Linux AMI 2018.03.0.20180811 x86_64 HVM GP2 ami-0ebc281c20e89ba4b
Retenons l’AMI ami-0ebc281c20e89ba4b
comme la plus récente.
export AWS_IMAGE="ami-0ebc281c20e89ba4b"
Exemple : Rechercher l’AMI Amazon Linux 2 actuelle
aws ec2 describe-images --owners amazon \
--filters 'Name=name,Values=amzn2-ami-hvm-2.0.????????-x86_64-gp2' 'Name=state,Values=available' \
--output json | jq -r '.Images | sort_by(.CreationDate) | last(.[]).ImageId'
Exemple : Rechercher l’AMI Amazon Linux actuelle
aws ec2 describe-images --owners amazon \
--filters 'Name=name,Values=amzn-ami-hvm-????.??.?.????????-x86_64-gp2' 'Name=state,Values=available' \
--output json | jq -r '.Images | sort_by(.CreationDate) | last(.[]).ImageId'
Exemple : Rechercher l’AMI Ubuntu Server 18.04 LTS actuelle
aws ec2 describe-images --owners 099720109477 \
--filters 'Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-????????' 'Name=state,Values=available' \
--output json | jq -r '.Images | sort_by(.CreationDate) | last(.[]).ImageId'
Exemple : Rechercher l’AMI Red Hat Enterprise Linux 7.6 actuelle
aws ec2 describe-images --owners 309956199498 \
--filters 'Name=name,Values=RHEL-7.6_HVM_GA*' 'Name=state,Values=available' \
--output json | jq -r '.Images | sort_by(.CreationDate) | last(.[]).ImageId'
Exemple : Rechercher l’AMI SUSE Linux Enterprise Server 15 actuelle
aws ec2 describe-images --owners amazon \
--filters 'Name=name,Values=suse-sles-15-v????????-hvm-ssd-x86_64' 'Name=state,Values=available' \
--output json | jq -r '.Images | sort_by(.CreationDate) | last(.[]).ImageId'
Un Virtual Private Cloud (VPC) est un réseau virtuel dédié logiquement isolé des autres réseaux virtuels dans le cloud AWS. On peut lancer des ressources AWS, comme des instances Amazon EC2, dans un VPC, spécifier une plage d’adresses IP pour le VPC, ajouter des sous-réseaux, associer des groupes de sécurité et configurer des tables de routage.
Un sous-réseau est une plage d’adresses IP dans le VPC.
aws ec2 describe-vpcs --output table
--------------------------------------------------
| DescribeVpcs |
+------------------------------------------------+
|| Vpcs ||
|+-----------------------+----------------------+|
|| CidrBlock | 172.31.0.0/16 ||
|| DhcpOptionsId | dopt-93e8ccfa ||
|| InstanceTenancy | default ||
|| IsDefault | True ||
|| OwnerId | 733718180495 ||
|| State | available ||
|| VpcId | vpc-476c332e ||
|+-----------------------+----------------------+|
||| CidrBlockAssociationSet |||
||+----------------+---------------------------+||
||| AssociationId | vpc-cidr-assoc-a9c5c4c0 |||
||| CidrBlock | 172.31.0.0/16 |||
||+----------------+---------------------------+||
|||| CidrBlockState ||||
|||+---------------+--------------------------+|||
|||| State | associated ||||
|||+---------------+--------------------------+|||
export AWS_VPC="vpc-476c332e"
export AWS_VPC=$(aws ec2 describe-vpcs --query 'Vpcs[*].VpcId' --output text)
LABID="${USER}${RANDOM}"
aws ec2 create-security-group \
--group-name $LABID-demo-lab \
--description "$LABID Demo Lab Security Group" \
--vpc-id $AWS_VPC
aws ec2 authorize-security-group-ingress \
--group-name $LABID-demo-lab \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress \
--group-name $LABID-demo-lab \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress \
--group-name $LABID-demo-lab \
--protocol tcp \
--port 3000 \
--cidr 0.0.0.0/0
aws ec2 describe-security-groups \
--group-names $LABID-demo-lab \
--output table
----------------------------------------------------------
| DescribeSecurityGroups |
+--------------------------------------------------------+
|| SecurityGroups ||
|+--------------+---------------------------------------+|
|| Description | francois606 Demo Lab Security Group ||
|| GroupId | sg-0a518bf1e2fd2cc83 ||
|| GroupName | francois606-demo-lab ||
|| OwnerId | 733718180495 ||
|| VpcId | vpc-476c332e ||
|+--------------+---------------------------------------+|
||| IpPermissions |||
||+----------------------------------+-----------------+||
||| FromPort | 80 |||
||| IpProtocol | tcp |||
||| ToPort | 80 |||
||+----------------------------------+-----------------+||
|||| IpRanges ||||
|||+---------------------+----------------------------+|||
|||| CidrIp | 0.0.0.0/0 ||||
|||+---------------------+----------------------------+|||
||| IpPermissions |||
||+----------------------------------+-----------------+||
||| FromPort | 22 |||
||| IpProtocol | tcp |||
||| ToPort | 22 |||
||+----------------------------------+-----------------+||
|||| IpRanges ||||
|||+---------------------+----------------------------+|||
|||| CidrIp | 0.0.0.0/0 ||||
|||+---------------------+----------------------------+|||
||| IpPermissions |||
||+--------------------------------+-------------------+||
||| FromPort | 3000 |||
||| IpProtocol | tcp |||
||| ToPort | 3000 |||
||+--------------------------------+-------------------+||
|||| IpRanges ||||
|||+---------------------+----------------------------+|||
|||| CidrIp | 0.0.0.0/0 ||||
|||+---------------------+----------------------------+|||
||| IpPermissionsEgress |||
||+------------------------------------+---------------+||
||| IpProtocol | -1 |||
||+------------------------------------+---------------+||
|||| IpRanges ||||
|||+---------------------+----------------------------+|||
|||| CidrIp | 0.0.0.0/0 ||||
|||+---------------------+----------------------------+|||
On retiendra l’ID du groupe de sécurité
export AWS_SGID="sg-0a518bf1e2fd2cc83"
aws ec2 create-key-pair --key-name $LABID-demo-lab-key --query 'KeyMaterial' --output text > ~/.ssh/$LABID-demo-lab-key.pem
aws ec2 describe-key-pairs --key-name $LABID-demo-lab-key
{
"KeyPairs": [
{
"KeyName": "demo-lab-key",
"KeyFingerprint": "75:96:3c:ae:00:4f:27:88:af:35:52:a1:b9:cd:6d:0e:ff:2c:f4:58"
}
]
}
Restreindre les droits
chmod 400 ~/.ssh/$LABID-demo-lab-key.pem
aws ec2 run-instances \
--instance-type t2.micro \
--key-name $LABID-demo-lab-key \
--security-group-ids $AWS_SGID \
--image-id $AWS_IMAGE
{
"Instances": [
{
"Monitoring": {
"State": "disabled"
},
"PublicDnsName": "",
"StateReason": {
"Message": "pending",
"Code": "pending"
},
"State": {
"Code": 0,
"Name": "pending"
},
"EbsOptimized": false,
"LaunchTime": "2018-10-28T12:34:52.000Z",
"PrivateIpAddress": "172.31.35.250",
"ProductCodes": [],
"VpcId": "vpc-476c332e",
"CpuOptions": {
"CoreCount": 1,
"ThreadsPerCore": 1
},
"StateTransitionReason": "",
"InstanceId": "i-03f6971fddaff8558",
"ImageId": "ami-0ebc281c20e89ba4b",
"PrivateDnsName": "ip-172-31-35-250.eu-west-3.compute.internal",
"KeyName": "demo-lab-key",
"SecurityGroups": [
{
"GroupName": "demo-lab",
"GroupId": "sg-04edf90e659364a62"
}
],
"ClientToken": "",
"SubnetId": "subnet-074deb4a",
"InstanceType": "t2.micro",
"NetworkInterfaces": [
{
"Status": "in-use",
"MacAddress": "0e:3e:0a:fc:59:56",
"SourceDestCheck": true,
"VpcId": "vpc-476c332e",
"Description": "",
"NetworkInterfaceId": "eni-092f4bd7687ea0b89",
"PrivateIpAddresses": [
{
"PrivateDnsName": "ip-172-31-35-250.eu-west-3.compute.internal",
"Primary": true,
"PrivateIpAddress": "172.31.35.250"
}
],
"PrivateDnsName": "ip-172-31-35-250.eu-west-3.compute.internal",
"Attachment": {
"Status": "attaching",
"DeviceIndex": 0,
"DeleteOnTermination": true,
"AttachmentId": "eni-attach-0f2b364177e190547",
"AttachTime": "2018-10-28T12:34:52.000Z"
},
"Groups": [
{
"GroupName": "demo-lab",
"GroupId": "sg-04edf90e659364a62"
}
],
"Ipv6Addresses": [],
"OwnerId": "733718180495",
"SubnetId": "subnet-074deb4a",
"PrivateIpAddress": "172.31.35.250"
}
],
"SourceDestCheck": true,
"Placement": {
"Tenancy": "default",
"GroupName": "",
"AvailabilityZone": "eu-west-3c"
},
"Hypervisor": "xen",
"BlockDeviceMappings": [],
"Architecture": "x86_64",
"RootDeviceType": "ebs",
"RootDeviceName": "/dev/xvda",
"VirtualizationType": "hvm",
"AmiLaunchIndex": 0
}
],
"ReservationId": "r-091126bd779f312ce",
"Groups": [],
"OwnerId": "733718180495"
}
Amazon Elastic Compute Cloud (Amazon EC2) est un service Web qui fournit une capacité de calcul sécurisée et redimensionnable dans le cloud. Destiné aux développeurs, il est conçu pour faciliter l’accès aux ressources de cloud computing à l’échelle du Web.
Types de virtualisation AMI Linux
aws ec2 describe-instances
aws ec2 describe-instances --output table
aws ec2 describe-instances --filters "Name=instance.group-name,Values=$LABID-demo-lab"
aws ec2 describe-instances --filters "Name=instance-type,Values=t2.micro" --query Reservations[].Instances[].InstanceId
aws ec2 describe-instances --filters "Name=instance.group-name,Values=$LABID-demo-lab" --query Reservations[].Instances[].InstanceId --output text
i-01295da4c589e3178
export AWS_INSTANCE="$(aws ec2 describe-instances --filters "Name=instance.group-name,Values=$LABID-demo-lab" --query Reservations[].Instances[].InstanceId --output text)"
aws ec2 describe-instances \
--instance-ids $AWS_INSTANCE \
--query "Reservations[*].Instances[*].PublicDnsName" --output text
INSTANCE=$(aws ec2 describe-instances --instance-ids $AWS_INSTANCE --query "Reservations[*].Instances[*].PublicDnsName" --output text)
Pour une AMI Linux Amazon :
ssh -i ~/.ssh/$LABID-demo-lab-key.pem ec2-user@$INSTANCE
Pour une AMI Ubuntu :
ssh -i ~/.ssh/$LABID-demo-lab-key.pem ubuntu@$INSTANCE
aws ec2 stop-instances --instance-ids $AWS_INSTANCE && aws ec2 terminate-instances --instance-ids $AWS_INSTANCE
aws ec2 delete-key-pair --key-name $LABID-demo-lab-key
aws ec2 delete-security-group --group-name $LABID-demo-lab
Exécution de commandes sur votre instance Linux lors du lancement : on ajoute le paramètres --user-data file://my_script.sh
lors de la création de l’instance avec la commande aws ec2 run-instances
, my_script.sh
étant le script qui s’exécutera au démarrage. C’est la solution Cloud-init qui est utilisée dans ce cas. Beaucoup d’autres prestataires utilisent ce logiciel pour approvisionner des instances.
Voici un script Bash qui automatise la procédure de création d’une instance EC2, le contenu d’un fichier init.sh
configure l’instance (--user-data file://init.sh
) :
#!/bin/bash
# To Launch one Ubuntu Xenial EC2 instance
# Define several variables
DATE_ID=$(date +%s)
SG_NAME="ec2-sg-$DATE_ID"
KEY_NAME="ec2-key-$DATE_ID"
INSTANCE_TYPE="t2.micro"
SCRIPT="--user-data file://init.sh"
# Create a security group
echo -e "1. Create a security group"
SGID=$(aws ec2 create-security-group --group-name $SG_NAME \
--description "gitlab runner Security Group" \
--vpc-id $(aws ec2 describe-vpcs | jq -r .Vpcs[].VpcId) | jq -r .GroupId)
# Add an ingress rule for ssh management trafic
echo -e "2. Add an ingress rule for ssh management trafic"
aws ec2 authorize-security-group-ingress --group-name $SG_NAME \
--protocol tcp --port 22 --cidr 0.0.0.0/0
# Delete the old key anyway
echo -e "3. Delete the old SSH private key anyway"
rm -f ~/.ssh/$KEY_NAME.pem
# Create a new SSH private key
echo -e "4. Create a new SSH private key and restrict rights to only you"
aws ec2 create-key-pair --key-name $KEY_NAME --query 'KeyMaterial' \
--output text > ~/.ssh/$KEY_NAME.pem
# Restrict rights on the key
chmod 400 ~/.ssh/$KEY_NAME.pem
# Get an Ubuntu Xenial Image ID
echo -e "5. Get an Ubuntu Xenial Image ID"
IMAGE_ID=$(aws ec2 describe-images --owners 099720109477 \
--filters 'Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-????????' 'Name=state,Values=available' \
--output json | jq -r '.Images | sort_by(.CreationDate) | last(.[]).ImageId')
# Launch the EC2 instance
echo -e "6. Launch the EC2 instance with type, key name, security group and image id"
INSTANCE_ID=$(aws ec2 run-instances --instance-type $INSTANCE_TYPE --key-name $KEY_NAME \
--security-group-ids $SGID --image-id $IMAGE_ID $SCRIPT | jq -r '.Instances[] | .InstanceId')
# Get the instance ID
echo -e "7. Get the instance IP"
INSTANCE_IP=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID | jq -r .Reservations[].Instances[].PublicIpAddress)
# Store the connexion informations into the ~/aws-ec2-instances.csv
echo "$INSTANCE_ID,~/.ssh/$KEY_NAME.pem,$INSTANCE_IP" >> ~/aws-ec2-instances.csv
# Final Message
echo -e " To get an ssh terminal use this command:"
echo -e " ssh -i ~/.ssh/$KEY_NAME.pem ubuntu@$INSTANCE_IP"
echo -e " This information is stored in ~/aws-ec2-instances.csv"
Voici la script init.sh
:
#!/bin/bash
sudo apt upate && sudo apt -y install python-minimal