Pubblicato il 26/08/2023 da alnao nella categoria AWS

Elastic Compute Cloud, abbreviato con la sigla EC2, è servizio principale di servizio di calcolo (compute in inglese) nel Cloud di Amazon Web Services (AWS). Si tratta di un servizio che permette di avviare istanze remote per virtualizzare server o desktop con la posssilità di configurare la sicurezza, networking, storage, capacity e molto altro. Il servizio permette di gestire processi molto pesanti ma anche molti piccoli grazie alla scalabilità che permette di ridimensionare le istanze in base alle necessità di calcolo e al carico di lavoro. Questo non è un articolo che tratta di questo servizio nello specifico, si rimanda alla documentazione ufficiale per tutti i dettagli a riguardo, si da per scontato che un utente abbia almeno le conoscenze basi del servizio EC2 come i SecurityGroup, la gestione delle chiavi KeyPair, gli storage EBS e il bilanciamento del traffico ELB.

Questo articolo ha lo scopo di descrivere i principali comandi per la gestione delle istanze EC2 nel cloud usando gli strumenti messi a disposizione da AWS come la CLI, il servizio CloudFormation e le librerie CDK/SDK, lo scopo finale è automatizzare la gestione del servizio di virtualizzazione EC2.


La CLI mette a disposizione un unico comando con alcuni sottocomandi, tutte le informazioni sono disponibili nel solito sito ufficiale. I principali comandi sono:

  • recuperare l’elenco di tutte le istanze:
    aws ec2 describe-instances
  • recuperare il dettaglio di una istanza partendo dal nome dell’instanza (come tag name):
    aws ec2 describe-instances --filters "Name=tag:Name,Values=testAlberto"
  • recuperare il dettaglio di una istanza partendo dal id istanza:
    aws ec2 describe-instances --instance-ids i-094d7505c54b0xxxx
  • filtrare i dati ritornati dai precedenti comandi per ottenere solo alcuni dati delle istanze (come id, stato e indirizzi ip):
    aws ec2 describe-instances --instance-ids i-094d7505c54b0xxxx 
       --query "Reservations[*].Instances[*].[InstanceId, ImageId, 
         State, PrivateIpAddress, PublicIpAddress]"
  • impostare un tag di una istanza per assegnare un nome alla istanza:
    aws ec2 create-tags --resources i-094d7505c54b0xxxx 
       --tags Key=Name,Value=testAlbertoLinux3b
  • eseguire lo stop di una istanza:
    aws ec2 stop-instances --instance-ids i-094d7505c54b0xxxx
  • eseguire il comando di start di una istanza:
    aws ec2 start-instances --instance-ids i-094d7505c54b0xxxx

Quasi tutti i comandi ritornano i dati secondo il fomato specifico al momento della configurazione della AWS-CLI, se si è impostato il tipo Json le risposte saranno del tipo:

{"StartingInstances": [{
  "CurrentState": {
    "Code": 0,
    "Name": "pending"
  },
  "InstanceId": "i-094d7505c54b0e029",
  "PreviousState": {
    "Code": 80,
    "Name": "stopped"
  }
} ] }

L’elenco completo di tutti i parametri e i possibili utilizzi è disponibile nelle pagine dedicate nella pagina ufficiale: ec2 e describe-instances. Per creare/avviare una nuova istanza è disponibile il comando run-instances, documentato nella pagina ufficiale, il comando ha alcuni parametri obbligatori che corrispono ai dati obbligatori per l’avvio di una istanze EC2 da console:

  • immagine ami
  • numero di istanze da avviare
  • tipo (consigliato t2.micro)
  • chiavi di accesso (se si tratta di istanza Linux)
  • security group
  • subnet-id

Un semplice esempio di avvio nella AZ Irlandese è:

aws ec2 run-instances --image-id ami-06e0ce9d3339xxxx --count 1 
  --instance-type t2.micro --key-name Keeeey 
  --security-group-ids sg-0f2d1afe5832e7xxxx 
  --subnet-id subnet-0b6f53c0291c1xxxx

La risposta di questo comando è la conferma che una nuova istanza è stata avviata con tutti i dati, compresi quelli di default, alcuni dei principali dati ritornati dal json sono:

"ImageId": "ami-06e0ce9d3339cb039",
"InstanceId": "i-02849762f5cf6d1e1",
"Placement": {
  "AvailabilityZone": "eu-west-1b",
  "GroupName": "",
  "Tenancy": "default"
},
"PrivateDnsName": "ip-10-199-12-207.eu-west-1.compute.internal",
"PrivateIpAddress": "10.199.12.207",
"PublicDnsName": "",
"State": {
  "Code": 0,
  "Name": "running"
},

Per terminare l’istanza esiste un comando specifico, ben documentato nella pagina ufficiale, il comando ha bisogno in input solo dell’istanza, per esempio:

aws ec2 terminate-instances --instance-ids i-02849762f5cf6xxxx

Con CloudFormation è possibile creare e gestire istanze EC2 in template con il tipo base “AWS::EC2::Instance”, ben documentato nella pagina ufficiale, i parametri minimi per avviare una istanza sono:

EC2Instance:
  Type: AWS::EC2::Instance
  Properties:
    InstanceType: !Ref 'InstanceType' # t2.micro free tier
    SecurityGroups: [!Ref 'InstanceSecurityGroup']
    KeyName: !Ref 'KeyName'
    ImageId: !Ref 'LatestAmiId'

L’esempio più semplice con solo i quattro parametri fondamentali è disponibile nel repository pubblico ufficiale di AWS:

github.com/awslabs/aws-cloudformation-templates/blob/master/aws/services/EC2/EC2InstanceWithSecurityGroupSample.yaml

Un esempio leggermente più complesso con la creazione di un web-server esposto in internet con uno script user-data e una configurazione più avanzata della rete è disponibile nel repository:

github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio02istanzeEC2

Da notare che, per creare uno stack da questo template, è necessario inserire tre parametri obbligatori: KeyName, VpcId e SubnetId mentre AMI, security group sono parametri con un valore di default.


La libreria CDK permette la creazione e l’avvio di istanze EC2 da codice con la libreria ufficiale, un semplice esempio di creazione con la libreria Java:

final Instance engineEC2Instance = Instance.Builder.create(this, id + "-ec2")
.instanceName(id + "-ec2")
.machineImage(armUbuntuMachineImage)
.securityGroup(securityGroup)
.instanceType(InstanceType.of(InstanceClass.BURSTABLE4_GRAVITON,InstanceSize.SMALL))
.vpcSubnets(SubnetSelection.builder()
.subnetType(SubnetType.PUBLIC).build())
.vpc(vpc)
.build();

maggiori informazioni sono disponibili nella documentazione ufficiale.


La libreria SDK mette a disposizioni tool per gestire le Istanze, la documentazione ufficiale descrive metodi e procedure disponibili per la gestione del servizio Ec2. Per creare istanze è disponibile metodo per Java specifico:

RunInstancesRequest runRequest = RunInstancesRequest.builder()
.imageId(amiId)
.instanceType(InstanceType.T1_MICRO)
.maxCount(1)
.minCount(1)
.build();
RunInstancesResponse response = ec2.runInstances(runRequest);
String instanceId = response.instances().get(0).instanceId();
Tag tag = Tag.builder().key("Name").value(name).build();
CreateTagsRequest tagRequest = CreateTagsRequest.builder()
.resources(instanceId).tags(tag).build();
ec2.createTags(tagRequest);

Per ottenere la lista delle istanze di un account è disponibile un metodo nella libreria specifica, si riporta un esempio dove si può notare che il metodo ritorna al massimo 100 (o 1000) elementi quindi si usa deve usare il sistema a token per ottenerere l’elenco completo:

Region region = Region.EU_WEST_1; //default irland
Ec2Client ec2 = Ec2Client.builder().region(region)
  .credentialsProvider( Profiles.loadCredentialFromFile() ).build();
do {
  DescribeInstancesRequest request = DescribeInstancesRequest.builder()
    .maxResults(6).nextToken(nextToken).build();
  DescribeInstancesResponse response = ec2.describeInstances(request);
  for (Reservation reservation : response.reservations()) {
    for (Instance instance : reservation.instances()) {
      list.add(instance);
    }
   }
   nextToken = response.nextToken();
} while (nextToken != null);
for (Instance instance : list) {
  System.out.println("Instance:" + instance.instanceId() 
  + " " + instance.tags().get(0).value()
  + " " + instance.instanceType() + " " + instance.state().name());
}

Per il linguaggio Python, la libreria SDK-Boto3 mette a disposizione metodi specifici simili a quelli disponibili per la libreria in linguaggio Java, per esempio i 4 metodi principali per gestire le istanze sono:
import boto3

def get_lista_istanze(profile_name):
  boto3.setup_default_session(profile_name=profile_name)
  ec2 = boto3.client('ec2')
  response = ec2.describe_instances()
  return response
def set_tag(instance_id, tag_key, tag_value):
  if tag_key=='':
    return 
  ec2 = boto3.resource('ec2')# region_name=AWS_REGION)
  tags=[{'Key': tag_key,'Value': tag_value}]
  instances = ec2.instances.filter(InstanceIds=[instance_id,],)
  for instance in instances:
    instance.create_tags(Tags=tags)
    print("set_tag " + instance_id)
  return tags
def stop_instance(instance_id):
  ec2_client = boto3.client('ec2')#, region_name=”us-west-2"
  print ("stop_instance " + instance_id)
  response = ec2_client.stop_instances(InstanceIds=[instance_id])
  return response
def start_instance(instance_id):
  ec2_client = boto3.client('ec2')
  print ("start_instance " + instance_id)
  response = ec2_client.start_instances(InstanceIds=[instance_id])
  return response

In questo gruppo di funzioni sono esposti i metodi per eseguire start e stop di una istanza, esiste anche il metodo “terminate” per terminare una istanza ma è sconsigliato prevedere questo tipo di operazioni da un programma se non strettamente necessario.

MENU