Ci sono altri AWS SDK esempi disponibili nel repository AWS Doc SDK Examples
Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
EC2Esempi di Amazon che utilizzano SDK for JavaScript (v3)
I seguenti esempi di codice mostrano come eseguire azioni e implementare scenari comuni utilizzando AWS SDK for JavaScript (v3) con AmazonEC2.
Le nozioni di base sono esempi di codice che mostrano come eseguire le operazioni essenziali all'interno di un servizio.
Le operazioni sono estratti di codice da programmi più grandi e devono essere eseguite nel contesto. Mentre le azioni mostrano come richiamare le singole funzioni di servizio, è possibile visualizzare le azioni nel loro contesto nei relativi scenari.
Gli scenari sono esempi di codice che mostrano come eseguire attività specifiche richiamando più funzioni all'interno di un servizio o combinandole con altre Servizi AWS.
Ogni esempio include un collegamento al codice sorgente completo, in cui è possibile trovare istruzioni su come configurare ed eseguire il codice nel contesto.
Nozioni di base
I seguenti esempi di codice mostrano come iniziare a usare AmazonEC2.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { DescribeSecurityGroupsCommand, EC2Client } from "@aws-sdk/client-ec2"; // Call DescribeSecurityGroups and display the result. export const main = async () => { const client = new EC2Client(); try { const { SecurityGroups } = await client.send( new DescribeSecurityGroupsCommand({}), ); const securityGroupList = SecurityGroups.slice(0, 9) .map((sg) => ` • ${sg.GroupId}: ${sg.GroupName}`) .join("\n"); console.log( "Hello, Amazon EC2! Let's list up to 10 of your security groups:", ); console.log(securityGroupList); } catch (err) { console.error(err); } }; // Call function if run directly. import { fileURLToPath } from "node:url"; if (process.argv[1] === fileURLToPath(import.meta.url)) { main(); }
-
Per API i dettagli, vedi DescribeSecurityGroups AWS SDK for JavaScriptAPIReference.
-
Argomenti
Nozioni di base
L'esempio di codice seguente mostra come:
Creare una coppia di chiavi e un gruppo di sicurezza.
Seleziona un'Amazon Machine Image (AMI) e un tipo di istanza compatibile, quindi crea un'istanza.
Arrestare e riavviare l'istanza.
Associazione di un indirizzo IP elastico all'istanza
Connettiti alla tua istanza conSSH, quindi pulisci le risorse.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. Questo file contiene un elenco di azioni comuni utilizzate conEC2. I passaggi sono costruiti con un framework Scenario che semplifica l'esecuzione di un esempio interattivo. Per il contesto completo, visita il GitHub repository.
import { tmpdir } from "node:os"; import { writeFile, mkdtemp, rm } from "node:fs/promises"; import { join } from "node:path"; import { get } from "node:http"; import { AllocateAddressCommand, AssociateAddressCommand, AuthorizeSecurityGroupIngressCommand, CreateKeyPairCommand, CreateSecurityGroupCommand, DeleteKeyPairCommand, DeleteSecurityGroupCommand, DisassociateAddressCommand, paginateDescribeImages, paginateDescribeInstances, paginateDescribeInstanceTypes, ReleaseAddressCommand, RunInstancesCommand, StartInstancesCommand, StopInstancesCommand, TerminateInstancesCommand, waitUntilInstanceStatusOk, waitUntilInstanceStopped, waitUntilInstanceTerminated, } from "@aws-sdk/client-ec2"; import { ScenarioAction, ScenarioInput, ScenarioOutput, } from "@aws-doc-sdk-examples/lib/scenario/index.js"; import { paginateGetParametersByPath, SSMClient } from "@aws-sdk/client-ssm"; /** * @typedef {{ * ec2Client: import('@aws-sdk/client-ec2').EC2Client, * errors: Error[], * keyPairId?: string, * tmpDirectory?: string, * securityGroupId?: string, * ipAddress?: string, * images?: import('@aws-sdk/client-ec2').Image[], * image?: import('@aws-sdk/client-ec2').Image, * instanceTypes?: import('@aws-sdk/client-ec2').InstanceTypeInfo[], * instanceId?: string, * instanceIpAddress?: string, * allocationId?: string, * allocatedIpAddress?: string, * associationId?: string, * }} State */ /** * A skip function provided to the `skipWhen` of a Step when you want * to ignore that step if any errors have occurred. * @param {State} state */ const skipWhenErrors = (state) => state.errors.length > 0; const MAX_WAITER_TIME_IN_SECONDS = 60 * 8; export const confirm = new ScenarioInput("confirmContinue", "Continue?", { type: "confirm", skipWhen: skipWhenErrors, }); export const exitOnNoConfirm = new ScenarioAction( "exitOnConfirmContinueFalse", (/** @type { { earlyExit: boolean } & Record<string, any>} */ state) => { if (!state[confirm.name]) { state.earlyExit = true; } }, { skipWhen: skipWhenErrors, }, ); export const greeting = new ScenarioOutput( "greeting", ` Welcome to the Amazon EC2 basic usage scenario. Before you launch an instances, you'll need to provide a few things: - A key pair - This is for SSH access to your EC2 instance. You only need to provide the name. - A security group - This is used for configuring access to your instance. Again, only the name is needed. - An IP address - Your public IP address will be fetched. - An Amazon Machine Image (AMI) - A compatible instance type`, { header: true, preformatted: true, skipWhen: skipWhenErrors }, ); export const provideKeyPairName = new ScenarioInput( "keyPairName", "Provide a name for a new key pair.", { type: "input", default: "ec2-example-key-pair", skipWhen: skipWhenErrors }, ); export const createKeyPair = new ScenarioAction( "createKeyPair", async (/** @type {State} */ state) => { try { // Create a key pair in Amazon EC2. const { KeyMaterial, KeyPairId } = await state.ec2Client.send( // A unique name for the key pair. Up to 255 ASCII characters. new CreateKeyPairCommand({ KeyName: state[provideKeyPairName.name] }), ); state.keyPairId = KeyPairId; // Save the private key in a temporary location. state.tmpDirectory = await mkdtemp(join(tmpdir(), "ec2-scenario-tmp")); await writeFile( `${state.tmpDirectory}/${state[provideKeyPairName.name]}.pem`, KeyMaterial, { mode: 0o400, }, ); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidKeyPair.Duplicate" ) { caught.message = `${caught.message}. Try another key name.`; } state.errors.push(caught); } }, { skipWhen: skipWhenErrors }, ); export const logKeyPair = new ScenarioOutput( "logKeyPair", (/** @type {State} */ state) => `Created the key pair ${state[provideKeyPairName.name]}.`, { skipWhen: skipWhenErrors }, ); export const confirmDeleteKeyPair = new ScenarioInput( "confirmDeleteKeyPair", "Do you want to delete the key pair?", { type: "confirm", // Don't do anything when a key pair was never created. skipWhen: (/** @type {State} */ state) => !state.keyPairId, }, ); export const maybeDeleteKeyPair = new ScenarioAction( "deleteKeyPair", async (/** @type {State} */ state) => { try { // Delete a key pair by name from EC2 await state.ec2Client.send( new DeleteKeyPairCommand({ KeyName: state[provideKeyPairName.name] }), ); } catch (caught) { if ( caught instanceof Error && // Occurs when a required parameter (e.g. KeyName) is undefined. caught.name === "MissingParameter" ) { caught.message = `${caught.message}. Did you provide the required value?`; } state.errors.push(caught); } }, { // Don't do anything when there's no key pair to delete or the user chooses // to keep it. skipWhen: (/** @type {State} */ state) => !state.keyPairId || !state[confirmDeleteKeyPair.name], }, ); export const provideSecurityGroupName = new ScenarioInput( "securityGroupName", "Provide a name for a new security group.", { type: "input", default: "ec2-scenario-sg", skipWhen: skipWhenErrors }, ); export const createSecurityGroup = new ScenarioAction( "createSecurityGroup", async (/** @type {State} */ state) => { try { // Create a new security group that will be used to configure ingress/egress for // an EC2 instance. const { GroupId } = await state.ec2Client.send( new CreateSecurityGroupCommand({ GroupName: state[provideSecurityGroupName.name], Description: "A security group for the Amazon EC2 example.", }), ); state.securityGroupId = GroupId; } catch (caught) { if (caught instanceof Error && caught.name === "InvalidGroup.Duplicate") { caught.message = `${caught.message}. Please provide a different name for your security group.`; } state.errors.push(caught); } }, { skipWhen: skipWhenErrors }, ); export const logSecurityGroup = new ScenarioOutput( "logSecurityGroup", (/** @type {State} */ state) => `Created the security group ${state.securityGroupId}.`, { skipWhen: skipWhenErrors }, ); export const confirmDeleteSecurityGroup = new ScenarioInput( "confirmDeleteSecurityGroup", "Do you want to delete the security group?", { type: "confirm", // Don't do anything when a security group was never created. skipWhen: (/** @type {State} */ state) => !state.securityGroupId, }, ); export const maybeDeleteSecurityGroup = new ScenarioAction( "deleteSecurityGroup", async (/** @type {State} */ state) => { try { // Delete the security group if the 'skipWhen' condition below is not met. await state.ec2Client.send( new DeleteSecurityGroupCommand({ GroupId: state.securityGroupId, }), ); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidGroupId.Malformed" ) { caught.message = `${caught.message}. Please provide a valid GroupId.`; } state.errors.push(caught); } }, { // Don't do anything when there's no security group to delete // or the user chooses to keep it. skipWhen: (/** @type {State} */ state) => !state.securityGroupId || !state[confirmDeleteSecurityGroup.name], }, ); export const authorizeSecurityGroupIngress = new ScenarioAction( "authorizeSecurity", async (/** @type {State} */ state) => { try { // Get the public IP address of the machine running this example. const ipAddress = await new Promise((res, rej) => { get("http://checkip.amazonaws.com", (response) => { let data = ""; response.on("data", (chunk) => { data += chunk; }); response.on("end", () => res(data.trim())); }).on("error", (err) => { rej(err); }); }); state.ipAddress = ipAddress; // Allow ingress from the IP address above to the security group. // This will allow you to SSH into the EC2 instance. const command = new AuthorizeSecurityGroupIngressCommand({ GroupId: state.securityGroupId, IpPermissions: [ { IpProtocol: "tcp", FromPort: 22, ToPort: 22, IpRanges: [{ CidrIp: `${ipAddress}/32` }], }, ], }); await state.ec2Client.send(command); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidGroupId.Malformed" ) { caught.message = `${caught.message}. Please provide a valid GroupId.`; } state.errors.push(caught); } }, { skipWhen: skipWhenErrors }, ); export const logSecurityGroupIngress = new ScenarioOutput( "logSecurityGroupIngress", (/** @type {State} */ state) => `Allowed SSH access from your public IP: ${state.ipAddress}.`, { skipWhen: skipWhenErrors }, ); export const getImages = new ScenarioAction( "images", async (/** @type {State} */ state) => { const AMIs = []; // Some AWS services publish information about common artifacts as AWS Systems Manager (SSM) // public parameters. For example, the Amazon Elastic Compute Cloud (Amazon EC2) // service publishes information about Amazon Machine Images (AMIs) as public parameters. // Create the paginator for getting images. Actions that return multiple pages of // results have paginators to simplify those calls. const getParametersByPathPaginator = paginateGetParametersByPath( { // Not storing this client in state since it's only used once. client: new SSMClient({}), }, { // The path to the public list of the latest amazon-linux instances. Path: "/aws/service/ami-amazon-linux-latest", }, ); try { for await (const page of getParametersByPathPaginator) { for (const param of page.Parameters) { // Filter by Amazon Linux 2 if (param.Name.includes("amzn2")) { AMIs.push(param.Value); } } } } catch (caught) { if (caught instanceof Error && caught.name === "InvalidFilterValue") { caught.message = `${caught.message} Please provide a valid filter value for paginateGetParametersByPath.`; } state.errors.push(caught); return; } const imageDetails = []; const describeImagesPaginator = paginateDescribeImages( { client: state.ec2Client }, // The images found from the call to SSM. { ImageIds: AMIs }, ); try { // Get more details for the images found above. for await (const page of describeImagesPaginator) { imageDetails.push(...(page.Images || [])); } // Store the image details for later use. state.images = imageDetails; } catch (caught) { if (caught instanceof Error && caught.name === "InvalidAMIID.NotFound") { caught.message = `${caught.message}. Please provide a valid image id.`; } state.errors.push(caught); } }, { skipWhen: skipWhenErrors }, ); export const provideImage = new ScenarioInput( "image", "Select one of the following images.", { type: "select", choices: (/** @type { State } */ state) => state.images.map((image) => ({ name: `${image.Description}`, value: image, })), default: (/** @type { State } */ state) => state.images[0], skipWhen: skipWhenErrors, }, ); export const getCompatibleInstanceTypes = new ScenarioAction( "getCompatibleInstanceTypes", async (/** @type {State} */ state) => { // Get more details about instance types that match the architecture of // the provided image. const paginator = paginateDescribeInstanceTypes( { client: state.ec2Client, pageSize: 25 }, { Filters: [ { Name: "processor-info.supported-architecture", // The value selected from provideImage() Values: [state.image.Architecture], }, // Filter for smaller, less expensive, types. { Name: "instance-type", Values: ["*.micro", "*.small"] }, ], }, ); const instanceTypes = []; try { for await (const page of paginator) { if (page.InstanceTypes.length) { instanceTypes.push(...(page.InstanceTypes || [])); } } if (!instanceTypes.length) { state.errors.push( "No instance types matched the instance type filters.", ); } } catch (caught) { if (caught instanceof Error && caught.name === "InvalidParameterValue") { caught.message = `${caught.message}. Please check the provided values and try again.`; } state.errors.push(caught); } state.instanceTypes = instanceTypes; }, { skipWhen: skipWhenErrors }, ); export const provideInstanceType = new ScenarioInput( "instanceType", "Select an instance type.", { choices: (/** @type {State} */ state) => state.instanceTypes.map((instanceType) => ({ name: `${instanceType.InstanceType} - Memory:${instanceType.MemoryInfo.SizeInMiB}`, value: instanceType.InstanceType, })), type: "select", default: (/** @type {State} */ state) => state.instanceTypes[0].InstanceType, skipWhen: skipWhenErrors, }, ); export const runInstance = new ScenarioAction( "runInstance", async (/** @type { State } */ state) => { const { Instances } = await state.ec2Client.send( new RunInstancesCommand({ KeyName: state[provideKeyPairName.name], SecurityGroupIds: [state.securityGroupId], ImageId: state.image.ImageId, InstanceType: state[provideInstanceType.name], // Availability Zones have capacity limitations that may impact your ability to launch instances. // The `RunInstances` operation will only succeed if it can allocate at least the `MinCount` of instances. // However, EC2 will attempt to launch up to the `MaxCount` of instances, even if the full request cannot be satisfied. // If you need a specific number of instances, use `MinCount` and `MaxCount` set to the same value. // If you want to launch up to a certain number of instances, use `MaxCount` and let EC2 provision as many as possible. // If you require a minimum number of instances, but do not want to exceed a maximum, use both `MinCount` and `MaxCount`. MinCount: 1, MaxCount: 1, }), ); state.instanceId = Instances[0].InstanceId; try { // Poll `DescribeInstanceStatus` until status is "ok". await waitUntilInstanceStatusOk( { client: state.ec2Client, maxWaitTime: MAX_WAITER_TIME_IN_SECONDS, }, { InstanceIds: [Instances[0].InstanceId] }, ); } catch (caught) { if (caught instanceof Error && caught.name === "TimeoutError") { caught.message = `${caught.message}. Try increasing the maxWaitTime in the waiter.`; } state.errors.push(caught); } }, { skipWhen: skipWhenErrors }, ); export const logRunInstance = new ScenarioOutput( "logRunInstance", "The next step is to run your EC2 instance for the first time. This can take a few minutes.", { header: true, skipWhen: skipWhenErrors }, ); export const describeInstance = new ScenarioAction( "describeInstance", async (/** @type { State } */ state) => { /** @type { import("@aws-sdk/client-ec2").Instance[] } */ const instances = []; try { const paginator = paginateDescribeInstances( { client: state.ec2Client, }, { // Only get our created instance. InstanceIds: [state.instanceId], }, ); for await (const page of paginator) { for (const reservation of page.Reservations) { instances.push(...reservation.Instances); } } if (instances.length !== 1) { throw new Error(`Instance ${state.instanceId} not found.`); } // The only info we need is the IP address for SSH purposes. state.instanceIpAddress = instances[0].PublicIpAddress; } catch (caught) { if (caught instanceof Error && caught.name === "InvalidParameterValue") { caught.message = `${caught.message}. Please check provided values and try again.`; } state.errors.push(caught); } }, { skipWhen: skipWhenErrors }, ); export const logSSHConnectionInfo = new ScenarioOutput( "logSSHConnectionInfo", (/** @type { State } */ state) => `You can now SSH into your instance using the following command: ssh -i ${state.tmpDirectory}/${state[provideKeyPairName.name]}.pem ec2-user@${state.instanceIpAddress}`, { preformatted: true, skipWhen: skipWhenErrors }, ); export const logStopInstance = new ScenarioOutput( "logStopInstance", "Stopping your EC2 instance.", { skipWhen: skipWhenErrors }, ); export const stopInstance = new ScenarioAction( "stopInstance", async (/** @type { State } */ state) => { try { await state.ec2Client.send( new StopInstancesCommand({ InstanceIds: [state.instanceId], }), ); await waitUntilInstanceStopped( { client: state.ec2Client, maxWaitTime: MAX_WAITER_TIME_IN_SECONDS, }, { InstanceIds: [state.instanceId] }, ); } catch (caught) { if (caught instanceof Error && caught.name === "TimeoutError") { caught.message = `${caught.message}. Try increasing the maxWaitTime in the waiter.`; } state.errors.push(caught); } }, // Don't try to stop an instance that doesn't exist. { skipWhen: (/** @type { State } */ state) => !state.instanceId }, ); export const logIpAddressBehavior = new ScenarioOutput( "logIpAddressBehavior", [ "When you run an instance, by default it's assigned an IP address.", "That IP address is not static. It will change every time the instance is restarted.", "The next step is to stop and restart your instance to demonstrate this behavior.", ].join(" "), { header: true, skipWhen: skipWhenErrors }, ); export const logStartInstance = new ScenarioOutput( "logStartInstance", (/** @type { State } */ state) => `Starting instance ${state.instanceId}`, { skipWhen: skipWhenErrors }, ); export const startInstance = new ScenarioAction( "startInstance", async (/** @type { State } */ state) => { try { await state.ec2Client.send( new StartInstancesCommand({ InstanceIds: [state.instanceId], }), ); await waitUntilInstanceStatusOk( { client: state.ec2Client, maxWaitTime: MAX_WAITER_TIME_IN_SECONDS, }, { InstanceIds: [state.instanceId] }, ); } catch (caught) { if (caught instanceof Error && caught.name === "TimeoutError") { caught.message = `${caught.message}. Try increasing the maxWaitTime in the waiter.`; } state.errors.push(caught); } }, { skipWhen: skipWhenErrors }, ); export const logIpAllocation = new ScenarioOutput( "logIpAllocation", [ "It is possible to have a static IP address.", "To demonstrate this, an IP will be allocated and associated to your EC2 instance.", ].join(" "), { header: true, skipWhen: skipWhenErrors }, ); export const allocateIp = new ScenarioAction( "allocateIp", async (/** @type { State } */ state) => { try { // An Elastic IP address is allocated to your AWS account, and is yours until you release it. const { AllocationId, PublicIp } = await state.ec2Client.send( new AllocateAddressCommand({}), ); state.allocationId = AllocationId; state.allocatedIpAddress = PublicIp; } catch (caught) { if (caught instanceof Error && caught.name === "MissingParameter") { caught.message = `${caught.message}. Did you provide these values?`; } state.errors.push(caught); } }, { skipWhen: skipWhenErrors }, ); export const associateIp = new ScenarioAction( "associateIp", async (/** @type { State } */ state) => { try { // Associate an allocated IP address to an EC2 instance. An IP address can be allocated // with the AllocateAddress action. const { AssociationId } = await state.ec2Client.send( new AssociateAddressCommand({ AllocationId: state.allocationId, InstanceId: state.instanceId, }), ); state.associationId = AssociationId; // Update the IP address that is being tracked to match // the one just associated. state.instanceIpAddress = state.allocatedIpAddress; } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidAllocationID.NotFound" ) { caught.message = `${caught.message}. Did you provide the ID of a valid Elastic IP address AllocationId?`; } state.errors.push(caught); } }, { skipWhen: skipWhenErrors }, ); export const logStaticIpProof = new ScenarioOutput( "logStaticIpProof", "The IP address should remain the same even after stopping and starting the instance.", { header: true, skipWhen: skipWhenErrors }, ); export const logCleanUp = new ScenarioOutput( "logCleanUp", "That's it! You can choose to clean up the resources now, or clean them up on your own later.", { header: true, skipWhen: skipWhenErrors }, ); export const confirmDisassociateAddress = new ScenarioInput( "confirmDisassociateAddress", "Do you want to disassociate and release the static IP address created earlier?", { type: "confirm", skipWhen: (/** @type { State } */ state) => !state.associationId, }, ); export const maybeDisassociateAddress = new ScenarioAction( "maybeDisassociateAddress", async (/** @type { State } */ state) => { try { await state.ec2Client.send( new DisassociateAddressCommand({ AssociationId: state.associationId, }), ); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidAssociationID.NotFound" ) { caught.message = `${caught.message}. Please provide a valid association ID.`; } state.errors.push(caught); } }, { skipWhen: (/** @type { State } */ state) => !state[confirmDisassociateAddress.name] || !state.associationId, }, ); export const maybeReleaseAddress = new ScenarioAction( "maybeReleaseAddress", async (/** @type { State } */ state) => { try { await state.ec2Client.send( new ReleaseAddressCommand({ AllocationId: state.allocationId, }), ); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidAllocationID.NotFound" ) { caught.message = `${caught.message}. Please provide a valid AllocationID.`; } state.errors.push(caught); } }, { skipWhen: (/** @type { State } */ state) => !state[confirmDisassociateAddress.name] || !state.allocationId, }, ); export const confirmTerminateInstance = new ScenarioInput( "confirmTerminateInstance", "Do you want to terminate the instance?", // Don't do anything when an instance was never run. { skipWhen: (/** @type { State } */ state) => !state.instanceId, type: "confirm", }, ); export const maybeTerminateInstance = new ScenarioAction( "terminateInstance", async (/** @type { State } */ state) => { try { await state.ec2Client.send( new TerminateInstancesCommand({ InstanceIds: [state.instanceId], }), ); await waitUntilInstanceTerminated( { client: state.ec2Client }, { InstanceIds: [state.instanceId] }, ); } catch (caught) { if (caught instanceof Error && caught.name === "TimeoutError") { caught.message = `${caught.message}. Try increasing the maxWaitTime in the waiter.`; } state.errors.push(caught); } }, { // Don't do anything when there's no instance to terminate or the // use chooses not to terminate. skipWhen: (/** @type { State } */ state) => !state.instanceId || !state[confirmTerminateInstance.name], }, ); export const deleteTemporaryDirectory = new ScenarioAction( "deleteTemporaryDirectory", async (/** @type { State } */ state) => { try { await rm(state.tmpDirectory, { recursive: true }); } catch (caught) { state.errors.push(caught); } }, ); export const logErrors = new ScenarioOutput( "logErrors", (/** @type {State}*/ state) => { const errorList = state.errors .map((err) => ` - ${err.name}: ${err.message}`) .join("\n"); return `Scenario errors found:\n${errorList}`; }, { preformatted: true, header: true, // Don't log errors when there aren't any! skipWhen: (/** @type {State} */ state) => state.errors.length === 0, }, );
-
Per API i dettagli, consulta i seguenti argomenti in AWS SDK for JavaScript APIReference.
-
Azioni
Il seguente esempio di codice mostra come utilizzareAllocateAddress
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { AllocateAddressCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Allocates an Elastic IP address to your AWS account. */ export const main = async () => { const client = new EC2Client({}); const command = new AllocateAddressCommand({}); try { const { AllocationId, PublicIp } = await client.send(command); console.log("A new IP address has been allocated to your account:"); console.log(`ID: ${AllocationId} Public IP: ${PublicIp}`); console.log( "You can view your IP addresses in the AWS Management Console for Amazon EC2. Look under Network & Security > Elastic IPs", ); } catch (caught) { if (caught instanceof Error && caught.name === "MissingParameter") { console.warn(`${caught.message}. Did you provide these values?`); } else { throw caught; } } }; import { fileURLToPath } from "node:url"; // Call function if run directly. if (process.argv[1] === fileURLToPath(import.meta.url)) { main(); }
-
Per API i dettagli, vedi AllocateAddress AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareAssociateAddress
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { AssociateAddressCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Associates an Elastic IP address, or carrier IP address (for instances that are in subnets in Wavelength Zones) * with an instance or a network interface. * @param {{ instanceId: string, allocationId: string }} options */ export const main = async ({ instanceId, allocationId }) => { const client = new EC2Client({}); const command = new AssociateAddressCommand({ // You need to allocate an Elastic IP address before associating it with an instance. // You can do that with the AllocateAddressCommand. AllocationId: allocationId, // You need to create an EC2 instance before an IP address can be associated with it. // You can do that with the RunInstancesCommand. InstanceId: instanceId, }); try { const { AssociationId } = await client.send(command); console.log( `Address with allocation ID ${allocationId} is now associated with instance ${instanceId}.`, `The association ID is ${AssociationId}.`, ); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidAllocationID.NotFound" ) { console.warn( `${caught.message}. Did you provide the ID of a valid Elastic IP address AllocationId?`, ); } else { throw caught; } } };
-
Per API i dettagli, vedi AssociateAddress AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareAuthorizeSecurityGroupIngress
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { AuthorizeSecurityGroupIngressCommand, EC2Client, } from "@aws-sdk/client-ec2"; /** * Adds the specified inbound (ingress) rules to a security group. * @param {{ groupId: string, ipAddress: string }} options */ export const main = async ({ groupId, ipAddress }) => { const client = new EC2Client({}); const command = new AuthorizeSecurityGroupIngressCommand({ // Use a group ID from the AWS console or // the DescribeSecurityGroupsCommand. GroupId: groupId, IpPermissions: [ { IpProtocol: "tcp", FromPort: 22, ToPort: 22, // The IP address to authorize. // For more information on this notation, see // https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation IpRanges: [{ CidrIp: `${ipAddress}/32` }], }, ], }); try { const { SecurityGroupRules } = await client.send(command); console.log(JSON.stringify(SecurityGroupRules, null, 2)); } catch (caught) { if (caught instanceof Error && caught.name === "InvalidGroupId.Malformed") { console.warn(`${caught.message}. Please provide a valid GroupId.`); } else { throw caught; } } };
-
Per API i dettagli, vedi AuthorizeSecurityGroupIngress AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareCreateKeyPair
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { CreateKeyPairCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Creates an ED25519 or 2048-bit RSA key pair with the specified name and in the specified PEM or PPK format. * Amazon EC2 stores the public key and displays the private key for you to save to a file. * @param {{ keyName: string }} options */ export const main = async ({ keyName }) => { const client = new EC2Client({}); const command = new CreateKeyPairCommand({ KeyName: keyName, }); try { const { KeyMaterial, KeyName } = await client.send(command); console.log(KeyName); console.log(KeyMaterial); } catch (caught) { if (caught instanceof Error && caught.name === "InvalidKeyPair.Duplicate") { console.warn(`${caught.message}. Try another key name.`); } else { throw caught; } } };
-
Per API i dettagli, vedi CreateKeyPair AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareCreateLaunchTemplate
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. const ssmClient = new SSMClient({}); const { Parameter } = await ssmClient.send( new GetParameterCommand({ Name: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2", }), ); const ec2Client = new EC2Client({}); await ec2Client.send( new CreateLaunchTemplateCommand({ LaunchTemplateName: NAMES.launchTemplateName, LaunchTemplateData: { InstanceType: "t3.micro", ImageId: Parameter.Value, IamInstanceProfile: { Name: NAMES.instanceProfileName }, UserData: readFileSync( join(RESOURCES_PATH, "server_startup_script.sh"), ).toString("base64"), KeyName: NAMES.keyPairName, }, }),
-
Per API i dettagli, vedi CreateLaunchTemplate AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareCreateSecurityGroup
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { CreateSecurityGroupCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Creates a security group. * @param {{ groupName: string, description: string }} options */ export const main = async ({ groupName, description }) => { const client = new EC2Client({}); const command = new CreateSecurityGroupCommand({ // Up to 255 characters in length. Cannot start with sg-. GroupName: groupName, // Up to 255 characters in length. Description: description, }); try { const { GroupId } = await client.send(command); console.log(GroupId); } catch (caught) { if (caught instanceof Error && caught.name === "InvalidParameterValue") { console.warn(`${caught.message}.`); } else { throw caught; } } };
-
Per API i dettagli, vedi CreateSecurityGroup AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDeleteKeyPair
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { DeleteKeyPairCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Deletes the specified key pair, by removing the public key from Amazon EC2. * @param {{ keyName: string }} options */ export const main = async ({ keyName }) => { const client = new EC2Client({}); const command = new DeleteKeyPairCommand({ KeyName: keyName, }); try { await client.send(command); console.log("Successfully deleted key pair."); } catch (caught) { if (caught instanceof Error && caught.name === "MissingParameter") { console.warn(`${caught.message}. Did you provide the required value?`); } else { throw caught; } } };
-
Per API i dettagli, vedi DeleteKeyPair AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDeleteLaunchTemplate
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. await client.send( new DeleteLaunchTemplateCommand({ LaunchTemplateName: NAMES.launchTemplateName, }), );
-
Per API i dettagli, vedi DeleteLaunchTemplate AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDeleteSecurityGroup
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { DeleteSecurityGroupCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Deletes a security group. * @param {{ groupId: string }} options */ export const main = async ({ groupId }) => { const client = new EC2Client({}); const command = new DeleteSecurityGroupCommand({ GroupId: groupId, }); try { await client.send(command); console.log("Security group deleted successfully."); } catch (caught) { if (caught instanceof Error && caught.name === "InvalidGroupId.Malformed") { console.warn(`${caught.message}. Please provide a valid GroupId.`); } else { throw caught; } } };
-
Per API i dettagli, vedi DeleteSecurityGroup AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeAddresses
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { DescribeAddressesCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Describes the specified Elastic IP addresses or all of your Elastic IP addresses. * @param {{ allocationId: string }} options */ export const main = async ({ allocationId }) => { const client = new EC2Client({}); const command = new DescribeAddressesCommand({ // You can omit this property to show all addresses. AllocationIds: [allocationId], }); try { const { Addresses } = await client.send(command); const addressList = Addresses.map((address) => ` • ${address.PublicIp}`); console.log("Elastic IP addresses:"); console.log(addressList.join("\n")); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidAllocationID.NotFound" ) { console.warn(`${caught.message}. Please provide a valid AllocationId.`); } else { throw caught; } } };
-
Per API i dettagli, vedi DescribeAddresses AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeIamInstanceProfileAssociations
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. const ec2Client = new EC2Client({}); const { IamInstanceProfileAssociations } = await ec2Client.send( new DescribeIamInstanceProfileAssociationsCommand({ Filters: [ { Name: "instance-id", Values: [state.targetInstance.InstanceId] }, ], }), );
-
Per API i dettagli, vedi DescribeIamInstanceProfileAssociations AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeImages
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, paginateDescribeImages } from "@aws-sdk/client-ec2"; /** * Describes the specified images (AMIs, AKIs, and ARIs) available to you or all of the images available to you. * @param {{ architecture: string, pageSize: number }} options */ export const main = async ({ architecture, pageSize }) => { pageSize = Number.parseInt(pageSize); const client = new EC2Client({}); // The paginate function is a wrapper around the base command. const paginator = paginateDescribeImages( // Without limiting the page size, this call can take a long time. pageSize is just sugar for // the MaxResults property in the base command. { client, pageSize }, { // There are almost 70,000 images available. Be specific with your filtering // to increase efficiency. // See https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-ec2/interfaces/describeimagescommandinput.html#filters Filters: [{ Name: "architecture", Values: [architecture] }], }, ); /** * @type {import('@aws-sdk/client-ec2').Image[]} */ const images = []; let recordsScanned = 0; try { for await (const page of paginator) { recordsScanned += pageSize; if (page.Images.length) { images.push(...page.Images); break; } console.log( `No matching image found yet. Searched ${recordsScanned} records.`, ); } if (images.length) { console.log( `Found ${images.length} images:\n\n${images.map((image) => image.Name).join("\n")}\n`, ); } else { console.log( `No matching images found. Searched ${recordsScanned} records.\n`, ); } return images; } catch (caught) { if (caught instanceof Error && caught.name === "InvalidParameterValue") { console.warn(`${caught.message}`); return []; } throw caught; } };
-
Per API i dettagli, vedi DescribeImages AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeInstanceTypes
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, paginateDescribeInstanceTypes } from "@aws-sdk/client-ec2"; /** * Describes the specified instance types. By default, all instance types for the * current Region are described. Alternatively, you can filter the results. * @param {{ pageSize: string, supportedArch: string[], freeTier: boolean }} options */ export const main = async ({ pageSize, supportedArch, freeTier }) => { pageSize = Number.parseInt(pageSize); const client = new EC2Client({}); // The paginate function is a wrapper around the underlying command. const paginator = paginateDescribeInstanceTypes( // Without limiting the page size, this call can take a long time. pageSize is just sugar for // the MaxResults property in the underlying command. { client, pageSize }, { Filters: [ { Name: "processor-info.supported-architecture", Values: supportedArch, }, { Name: "free-tier-eligible", Values: [freeTier ? "true" : "false"] }, ], }, ); try { /** * @type {import('@aws-sdk/client-ec2').InstanceTypeInfo[]} */ const instanceTypes = []; for await (const page of paginator) { if (page.InstanceTypes.length) { instanceTypes.push(...page.InstanceTypes); // When we have at least 1 result, we can stop. if (instanceTypes.length >= 1) { break; } } } console.log( `Memory size in MiB for matching instance types:\n\n${instanceTypes.map((it) => `${it.InstanceType}: ${it.MemoryInfo.SizeInMiB} MiB`).join("\n")}`, ); } catch (caught) { if (caught instanceof Error && caught.name === "InvalidParameterValue") { console.warn(`${caught.message}`); return []; } throw caught; } };
-
Per API i dettagli, vedi DescribeInstanceTypes AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeInstances
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, paginateDescribeInstances } from "@aws-sdk/client-ec2"; /** * List all of your EC2 instances running with the provided architecture that * were launched in the past month. * @param {{ pageSize: string, architectures: string[] }} options */ export const main = async ({ pageSize, architectures }) => { pageSize = Number.parseInt(pageSize); const client = new EC2Client({}); const d = new Date(); const year = d.getFullYear(); const month = `0${d.getMonth() + 1}`.slice(-2); const launchTimePattern = `${year}-${month}-*`; const paginator = paginateDescribeInstances( { client, pageSize, }, { Filters: [ { Name: "architecture", Values: architectures }, { Name: "instance-state-name", Values: ["running"] }, { Name: "launch-time", Values: [launchTimePattern], }, ], }, ); try { /** * @type {import('@aws-sdk/client-ec2').Instance[]} */ const instanceList = []; for await (const page of paginator) { const { Reservations } = page; for (const reservation of Reservations) { instanceList.push(...reservation.Instances); } } console.log( `Running instances launched this month:\n\n${instanceList.map((instance) => instance.InstanceId).join("\n")}`, ); } catch (caught) { if (caught instanceof Error && caught.name === "InvalidParameterValue") { console.warn(`${caught.message}.`); } else { throw caught; } } };
-
Per API i dettagli, vedi DescribeInstances AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeKeyPairs
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { DescribeKeyPairsCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * List all key pairs in the current AWS account. * @param {{ dryRun: boolean }} */ export const main = async ({ dryRun }) => { const client = new EC2Client({}); const command = new DescribeKeyPairsCommand({ DryRun: dryRun }); try { const { KeyPairs } = await client.send(command); const keyPairList = KeyPairs.map( (kp) => ` • ${kp.KeyPairId}: ${kp.KeyName}`, ).join("\n"); console.log("The following key pairs were found in your account:"); console.log(keyPairList); } catch (caught) { if (caught instanceof Error && caught.name === "DryRunOperation") { console.log(`${caught.message}`); } else { throw caught; } } };
-
Per API i dettagli, vedi DescribeKeyPairs AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeRegions
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { DescribeRegionsCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * List all available AWS regions. * @param {{ regionNames: string[], includeOptInRegions: boolean }} options */ export const main = async ({ regionNames, includeOptInRegions }) => { const client = new EC2Client({}); const command = new DescribeRegionsCommand({ // By default this command will not show regions that require you to opt-in. // When AllRegions is true, even the regions that require opt-in will be returned. AllRegions: includeOptInRegions, // You can omit the Filters property if you want to get all regions. Filters: regionNames?.length ? [ { Name: "region-name", // You can specify multiple values for a filter. // You can also use '*' as a wildcard. This will return all // of the regions that start with `us-east-`. Values: regionNames, }, ] : undefined, }); try { const { Regions } = await client.send(command); const regionsList = Regions.map((reg) => ` • ${reg.RegionName}`); console.log("Found regions:"); console.log(regionsList.join("\n")); } catch (caught) { if (caught instanceof Error && caught.name === "DryRunOperation") { console.log(`${caught.message}`); } else { throw caught; } } };
-
Per API i dettagli, vedi DescribeRegions AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeSecurityGroups
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { DescribeSecurityGroupsCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Describes the specified security groups or all of your security groups. * @param {{ groupIds: string[] }} options */ export const main = async ({ groupIds = [] }) => { const client = new EC2Client({}); const command = new DescribeSecurityGroupsCommand({ GroupIds: groupIds, }); try { const { SecurityGroups } = await client.send(command); const sgList = SecurityGroups.map( (sg) => `• ${sg.GroupName} (${sg.GroupId}): ${sg.Description}`, ).join("\n"); if (sgList.length) { console.log(`Security groups:\n${sgList}`); } else { console.log("No security groups found."); } } catch (caught) { if (caught instanceof Error && caught.name === "InvalidGroupId.Malformed") { console.warn(`${caught.message}. Please provide a valid GroupId.`); } else if ( caught instanceof Error && caught.name === "InvalidGroup.NotFound" ) { console.warn(caught.message); } else { throw caught; } } };
-
Per API i dettagli, vedi DescribeSecurityGroups AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeSubnets
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. const client = new EC2Client({}); const { Subnets } = await client.send( new DescribeSubnetsCommand({ Filters: [ { Name: "vpc-id", Values: [state.defaultVpc] }, { Name: "availability-zone", Values: state.availabilityZoneNames }, { Name: "default-for-az", Values: ["true"] }, ], }), );
-
Per API i dettagli, vedi DescribeSubnets AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeVpcs
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. const client = new EC2Client({}); const { Vpcs } = await client.send( new DescribeVpcsCommand({ Filters: [{ Name: "is-default", Values: ["true"] }], }), );
-
Per API i dettagli, vedi DescribeVpcs AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDisassociateAddress
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { DisassociateAddressCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Disassociate an Elastic IP address from an instance. * @param {{ associationId: string }} options */ export const main = async ({ associationId }) => { const client = new EC2Client({}); const command = new DisassociateAddressCommand({ // You can also use PublicIp, but that is for EC2 classic which is being retired. AssociationId: associationId, }); try { await client.send(command); console.log("Successfully disassociated address"); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidAssociationID.NotFound" ) { console.warn(`${caught.message}.`); } else { throw caught; } } };
-
Per API i dettagli, vedi DisassociateAddress AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareMonitorInstances
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, MonitorInstancesCommand } from "@aws-sdk/client-ec2"; /** * Turn on detailed monitoring for the selected instance. * By default, metrics are sent to Amazon CloudWatch every 5 minutes. * For a cost you can enable detailed monitoring which sends metrics every minute. * @param {{ instanceIds: string[] }} options */ export const main = async ({ instanceIds }) => { const client = new EC2Client({}); const command = new MonitorInstancesCommand({ InstanceIds: instanceIds, }); try { const { InstanceMonitorings } = await client.send(command); const instancesBeingMonitored = InstanceMonitorings.map( (im) => ` • Detailed monitoring state for ${im.InstanceId} is ${im.Monitoring.State}.`, ); console.log("Monitoring status:"); console.log(instancesBeingMonitored.join("\n")); } catch (caught) { if (caught instanceof Error && caught.name === "InvalidParameterValue") { console.warn(`${caught.message}`); } else { throw caught; } } };
-
Per API i dettagli, vedi MonitorInstances AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareRebootInstances
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, RebootInstancesCommand } from "@aws-sdk/client-ec2"; /** * Requests a reboot of the specified instances. This operation is asynchronous; * it only queues a request to reboot the specified instances. * @param {{ instanceIds: string[] }} options */ export const main = async ({ instanceIds }) => { const client = new EC2Client({}); const command = new RebootInstancesCommand({ InstanceIds: instanceIds, }); try { await client.send(command); console.log("Instance rebooted successfully."); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidInstanceID.NotFound" ) { console.warn( `${caught.message}. Please provide the InstanceId of a valid instance to reboot.`, ); } else { throw caught; } } };
-
Per API i dettagli, vedi RebootInstances AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareReleaseAddress
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { ReleaseAddressCommand, EC2Client } from "@aws-sdk/client-ec2"; /** * Release an Elastic IP address. * @param {{ allocationId: string }} options */ export const main = async ({ allocationId }) => { const client = new EC2Client({}); const command = new ReleaseAddressCommand({ // You can also use PublicIp, but that is for EC2 classic which is being retired. AllocationId: allocationId, }); try { await client.send(command); console.log("Successfully released address."); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidAllocationID.NotFound" ) { console.warn(`${caught.message}. Please provide a valid AllocationID.`); } else { throw caught; } } };
-
Per API i dettagli, vedi ReleaseAddress AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareReplaceIamInstanceProfileAssociation
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. await retry({ intervalInMs: 1000, maxRetries: 30 }, () => ec2Client.send( new ReplaceIamInstanceProfileAssociationCommand({ AssociationId: state.instanceProfileAssociationId, IamInstanceProfile: { Name: NAMES.ssmOnlyInstanceProfileName }, }), ), );
-
Per API i dettagli, vedi ReplaceIamInstanceProfileAssociation AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareRunInstances
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, RunInstancesCommand } from "@aws-sdk/client-ec2"; /** * Create new EC2 instances. * @param {{ * keyName: string, * securityGroupIds: string[], * imageId: string, * instanceType: import('@aws-sdk/client-ec2')._InstanceType, * minCount?: number, * maxCount?: number }} options */ export const main = async ({ keyName, securityGroupIds, imageId, instanceType, minCount = "1", maxCount = "1", }) => { const client = new EC2Client({}); minCount = Number.parseInt(minCount); maxCount = Number.parseInt(maxCount); const command = new RunInstancesCommand({ // Your key pair name. KeyName: keyName, // Your security group. SecurityGroupIds: securityGroupIds, // An Amazon Machine Image (AMI). There are multiple ways to search for AMIs. For more information, see: // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html ImageId: imageId, // An instance type describing the resources provided to your instance. There are multiple // ways to search for instance types. For more information see: // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-discovery.html InstanceType: instanceType, // Availability Zones have capacity limitations that may impact your ability to launch instances. // The `RunInstances` operation will only succeed if it can allocate at least the `MinCount` of instances. // However, EC2 will attempt to launch up to the `MaxCount` of instances, even if the full request cannot be satisfied. // If you need a specific number of instances, use `MinCount` and `MaxCount` set to the same value. // If you want to launch up to a certain number of instances, use `MaxCount` and let EC2 provision as many as possible. // If you require a minimum number of instances, but do not want to exceed a maximum, use both `MinCount` and `MaxCount`. MinCount: minCount, MaxCount: maxCount, }); try { const { Instances } = await client.send(command); const instanceList = Instances.map( (instance) => `• ${instance.InstanceId}`, ).join("\n"); console.log(`Launched instances:\n${instanceList}`); } catch (caught) { if (caught instanceof Error && caught.name === "ResourceCountExceeded") { console.warn(`${caught.message}`); } else { throw caught; } } };
-
Per API i dettagli, vedi RunInstances AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareStartInstances
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, StartInstancesCommand } from "@aws-sdk/client-ec2"; import { fileURLToPath } from "node:url"; import { parseArgs } from "node:util"; /** * Starts an Amazon EBS-backed instance that you've previously stopped. * @param {{ instanceIds }} options */ export const main = async ({ instanceIds }) => { const client = new EC2Client({}); const command = new StartInstancesCommand({ InstanceIds: instanceIds, }); try { const { StartingInstances } = await client.send(command); const instanceIdList = StartingInstances.map( (instance) => ` • ${instance.InstanceId}`, ); console.log("Starting instances:"); console.log(instanceIdList.join("\n")); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidInstanceID.NotFound" ) { console.warn(`${caught.message}`); } else { throw caught; } } };
-
Per API i dettagli, vedi StartInstances AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareStopInstances
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, StopInstancesCommand } from "@aws-sdk/client-ec2"; import { fileURLToPath } from "node:url"; import { parseArgs } from "node:util"; /** * Stop one or more EC2 instances. * @param {{ instanceIds: string[] }} options */ export const main = async ({ instanceIds }) => { const client = new EC2Client({}); const command = new StopInstancesCommand({ InstanceIds: instanceIds, }); try { const { StoppingInstances } = await client.send(command); const instanceIdList = StoppingInstances.map( (instance) => ` • ${instance.InstanceId}`, ); console.log("Stopping instances:"); console.log(instanceIdList.join("\n")); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidInstanceID.NotFound" ) { console.warn(`${caught.message}`); } else { throw caught; } } };
-
Per API i dettagli, vedi StopInstances AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareTerminateInstances
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, TerminateInstancesCommand } from "@aws-sdk/client-ec2"; import { fileURLToPath } from "node:url"; import { parseArgs } from "node:util"; /** * Terminate one or more EC2 instances. * @param {{ instanceIds: string[] }} options */ export const main = async ({ instanceIds }) => { const client = new EC2Client({}); const command = new TerminateInstancesCommand({ InstanceIds: instanceIds, }); try { const { TerminatingInstances } = await client.send(command); const instanceList = TerminatingInstances.map( (instance) => ` • ${instance.InstanceId}`, ); console.log("Terminating instances:"); console.log(instanceList.join("\n")); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidInstanceID.NotFound" ) { console.warn(`${caught.message}`); } else { throw caught; } } };
-
Per API i dettagli, vedi TerminateInstances AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareUnmonitorInstances
.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. import { EC2Client, UnmonitorInstancesCommand } from "@aws-sdk/client-ec2"; import { fileURLToPath } from "node:url"; import { parseArgs } from "node:util"; /** * Turn off detailed monitoring for the selected instance. * @param {{ instanceIds: string[] }} options */ export const main = async ({ instanceIds }) => { const client = new EC2Client({}); const command = new UnmonitorInstancesCommand({ InstanceIds: instanceIds, }); try { const { InstanceMonitorings } = await client.send(command); const instanceMonitoringsList = InstanceMonitorings.map( (im) => ` • Detailed monitoring state for ${im.InstanceId} is ${im.Monitoring.State}.`, ); console.log("Monitoring status:"); console.log(instanceMonitoringsList.join("\n")); } catch (caught) { if ( caught instanceof Error && caught.name === "InvalidInstanceID.NotFound" ) { console.warn(`${caught.message}`); } else { throw caught; } } };
-
Per API i dettagli, vedi UnmonitorInstances AWS SDK for JavaScriptAPIReference.
-
Scenari
Il seguente esempio di codice mostra come creare un servizio Web con bilanciamento del carico che restituisca consigli su libri, film e canzoni. L'esempio mostra come il servizio risponde ai guasti e spiega come ristrutturarlo per una maggiore resilienza in caso di guasti.
Utilizza un gruppo Amazon EC2 Auto Scaling per creare istanze Amazon Elastic Compute Cloud (AmazonEC2) basate su un modello di avvio e per mantenere il numero di istanze in un intervallo specificato.
Gestisci e distribuisci HTTP le richieste con Elastic Load Balancing.
Monitora lo stato delle istanze in un gruppo con dimensionamento automatico e inoltra le richieste soltanto alle istanze integre.
Esegui un server web Python su ogni EC2 istanza per gestire le richieste. HTTP Il server Web risponde con consigli e controlli dell'integrità.
Simula un servizio di raccomandazione con una tabella Amazon DynamoDB.
Controlla la risposta del server web alle richieste e ai controlli di integrità aggiornando AWS Systems Manager i parametri.
- SDKper JavaScript (v3)
-
Nota
C'è di più su. GitHub Trova l'esempio completo e scopri di più sulla configurazione e l'esecuzione nel Repository di esempi di codice AWS
. Esegui lo scenario interattivo al prompt dei comandi.
#!/usr/bin/env node // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { Scenario, parseScenarioArgs, } from "@aws-doc-sdk-examples/lib/scenario/index.js"; /** * The workflow steps are split into three stages: * - deploy * - demo * - destroy * * Each of these stages has a corresponding file prefixed with steps-*. */ import { deploySteps } from "./steps-deploy.js"; import { demoSteps } from "./steps-demo.js"; import { destroySteps } from "./steps-destroy.js"; /** * The context is passed to every scenario. Scenario steps * will modify the context. */ const context = {}; /** * Three Scenarios are created for the workflow. A Scenario is an orchestration class * that simplifies running a series of steps. */ export const scenarios = { // Deploys all resources necessary for the workflow. deploy: new Scenario("Resilient Workflow - Deploy", deploySteps, context), // Demonstrates how a fragile web service can be made more resilient. demo: new Scenario("Resilient Workflow - Demo", demoSteps, context), // Destroys the resources created for the workflow. destroy: new Scenario("Resilient Workflow - Destroy", destroySteps, context), }; // Call function if run directly import { fileURLToPath } from "node:url"; if (process.argv[1] === fileURLToPath(import.meta.url)) { parseScenarioArgs(scenarios, { name: "Resilient Workflow", synopsis: "node index.js --scenario <deploy | demo | destroy> [-h|--help] [-y|--yes] [-v|--verbose]", description: "Deploy and interact with scalable EC2 instances.", }); }
Crea passaggi per distribuire tutte le risorse.
import { join } from "node:path"; import { readFileSync, writeFileSync } from "node:fs"; import axios from "axios"; import { BatchWriteItemCommand, CreateTableCommand, DynamoDBClient, waitUntilTableExists, } from "@aws-sdk/client-dynamodb"; import { EC2Client, CreateKeyPairCommand, CreateLaunchTemplateCommand, DescribeAvailabilityZonesCommand, DescribeVpcsCommand, DescribeSubnetsCommand, DescribeSecurityGroupsCommand, AuthorizeSecurityGroupIngressCommand, } from "@aws-sdk/client-ec2"; import { IAMClient, CreatePolicyCommand, CreateRoleCommand, CreateInstanceProfileCommand, AddRoleToInstanceProfileCommand, AttachRolePolicyCommand, waitUntilInstanceProfileExists, } from "@aws-sdk/client-iam"; import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"; import { CreateAutoScalingGroupCommand, AutoScalingClient, AttachLoadBalancerTargetGroupsCommand, } from "@aws-sdk/client-auto-scaling"; import { CreateListenerCommand, CreateLoadBalancerCommand, CreateTargetGroupCommand, ElasticLoadBalancingV2Client, waitUntilLoadBalancerAvailable, } from "@aws-sdk/client-elastic-load-balancing-v2"; import { ScenarioOutput, ScenarioInput, ScenarioAction, } from "@aws-doc-sdk-examples/lib/scenario/index.js"; import { saveState } from "@aws-doc-sdk-examples/lib/scenario/steps-common.js"; import { retry } from "@aws-doc-sdk-examples/lib/utils/util-timers.js"; import { MESSAGES, NAMES, RESOURCES_PATH, ROOT } from "./constants.js"; import { initParamsSteps } from "./steps-reset-params.js"; /** * @type {import('@aws-doc-sdk-examples/lib/scenario.js').Step[]} */ export const deploySteps = [ new ScenarioOutput("introduction", MESSAGES.introduction, { header: true }), new ScenarioInput("confirmDeployment", MESSAGES.confirmDeployment, { type: "confirm", }), new ScenarioAction( "handleConfirmDeployment", (c) => c.confirmDeployment === false && process.exit(), ), new ScenarioOutput( "creatingTable", MESSAGES.creatingTable.replace("${TABLE_NAME}", NAMES.tableName), ), new ScenarioAction("createTable", async () => { const client = new DynamoDBClient({}); await client.send( new CreateTableCommand({ TableName: NAMES.tableName, ProvisionedThroughput: { ReadCapacityUnits: 5, WriteCapacityUnits: 5, }, AttributeDefinitions: [ { AttributeName: "MediaType", AttributeType: "S", }, { AttributeName: "ItemId", AttributeType: "N", }, ], KeySchema: [ { AttributeName: "MediaType", KeyType: "HASH", }, { AttributeName: "ItemId", KeyType: "RANGE", }, ], }), ); await waitUntilTableExists({ client }, { TableName: NAMES.tableName }); }), new ScenarioOutput( "createdTable", MESSAGES.createdTable.replace("${TABLE_NAME}", NAMES.tableName), ), new ScenarioOutput( "populatingTable", MESSAGES.populatingTable.replace("${TABLE_NAME}", NAMES.tableName), ), new ScenarioAction("populateTable", () => { const client = new DynamoDBClient({}); /** * @type {{ default: import("@aws-sdk/client-dynamodb").PutRequest['Item'][] }} */ const recommendations = JSON.parse( readFileSync(join(RESOURCES_PATH, "recommendations.json")), ); return client.send( new BatchWriteItemCommand({ RequestItems: { [NAMES.tableName]: recommendations.map((item) => ({ PutRequest: { Item: item }, })), }, }), ); }), new ScenarioOutput( "populatedTable", MESSAGES.populatedTable.replace("${TABLE_NAME}", NAMES.tableName), ), new ScenarioOutput( "creatingKeyPair", MESSAGES.creatingKeyPair.replace("${KEY_PAIR_NAME}", NAMES.keyPairName), ), new ScenarioAction("createKeyPair", async () => { const client = new EC2Client({}); const { KeyMaterial } = await client.send( new CreateKeyPairCommand({ KeyName: NAMES.keyPairName, }), ); writeFileSync(`${NAMES.keyPairName}.pem`, KeyMaterial, { mode: 0o600 }); }), new ScenarioOutput( "createdKeyPair", MESSAGES.createdKeyPair.replace("${KEY_PAIR_NAME}", NAMES.keyPairName), ), new ScenarioOutput( "creatingInstancePolicy", MESSAGES.creatingInstancePolicy.replace( "${INSTANCE_POLICY_NAME}", NAMES.instancePolicyName, ), ), new ScenarioAction("createInstancePolicy", async (state) => { const client = new IAMClient({}); const { Policy: { Arn }, } = await client.send( new CreatePolicyCommand({ PolicyName: NAMES.instancePolicyName, PolicyDocument: readFileSync( join(RESOURCES_PATH, "instance_policy.json"), ), }), ); state.instancePolicyArn = Arn; }), new ScenarioOutput("createdInstancePolicy", (state) => MESSAGES.createdInstancePolicy .replace("${INSTANCE_POLICY_NAME}", NAMES.instancePolicyName) .replace("${INSTANCE_POLICY_ARN}", state.instancePolicyArn), ), new ScenarioOutput( "creatingInstanceRole", MESSAGES.creatingInstanceRole.replace( "${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName, ), ), new ScenarioAction("createInstanceRole", () => { const client = new IAMClient({}); return client.send( new CreateRoleCommand({ RoleName: NAMES.instanceRoleName, AssumeRolePolicyDocument: readFileSync( join(ROOT, "assume-role-policy.json"), ), }), ); }), new ScenarioOutput( "createdInstanceRole", MESSAGES.createdInstanceRole.replace( "${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName, ), ), new ScenarioOutput( "attachingPolicyToRole", MESSAGES.attachingPolicyToRole .replace("${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName) .replace("${INSTANCE_POLICY_NAME}", NAMES.instancePolicyName), ), new ScenarioAction("attachPolicyToRole", async (state) => { const client = new IAMClient({}); await client.send( new AttachRolePolicyCommand({ RoleName: NAMES.instanceRoleName, PolicyArn: state.instancePolicyArn, }), ); }), new ScenarioOutput( "attachedPolicyToRole", MESSAGES.attachedPolicyToRole .replace("${INSTANCE_POLICY_NAME}", NAMES.instancePolicyName) .replace("${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName), ), new ScenarioOutput( "creatingInstanceProfile", MESSAGES.creatingInstanceProfile.replace( "${INSTANCE_PROFILE_NAME}", NAMES.instanceProfileName, ), ), new ScenarioAction("createInstanceProfile", async (state) => { const client = new IAMClient({}); const { InstanceProfile: { Arn }, } = await client.send( new CreateInstanceProfileCommand({ InstanceProfileName: NAMES.instanceProfileName, }), ); state.instanceProfileArn = Arn; await waitUntilInstanceProfileExists( { client }, { InstanceProfileName: NAMES.instanceProfileName }, ); }), new ScenarioOutput("createdInstanceProfile", (state) => MESSAGES.createdInstanceProfile .replace("${INSTANCE_PROFILE_NAME}", NAMES.instanceProfileName) .replace("${INSTANCE_PROFILE_ARN}", state.instanceProfileArn), ), new ScenarioOutput( "addingRoleToInstanceProfile", MESSAGES.addingRoleToInstanceProfile .replace("${INSTANCE_PROFILE_NAME}", NAMES.instanceProfileName) .replace("${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName), ), new ScenarioAction("addRoleToInstanceProfile", () => { const client = new IAMClient({}); return client.send( new AddRoleToInstanceProfileCommand({ RoleName: NAMES.instanceRoleName, InstanceProfileName: NAMES.instanceProfileName, }), ); }), new ScenarioOutput( "addedRoleToInstanceProfile", MESSAGES.addedRoleToInstanceProfile .replace("${INSTANCE_PROFILE_NAME}", NAMES.instanceProfileName) .replace("${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName), ), ...initParamsSteps, new ScenarioOutput("creatingLaunchTemplate", MESSAGES.creatingLaunchTemplate), new ScenarioAction("createLaunchTemplate", async () => { const ssmClient = new SSMClient({}); const { Parameter } = await ssmClient.send( new GetParameterCommand({ Name: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2", }), ); const ec2Client = new EC2Client({}); await ec2Client.send( new CreateLaunchTemplateCommand({ LaunchTemplateName: NAMES.launchTemplateName, LaunchTemplateData: { InstanceType: "t3.micro", ImageId: Parameter.Value, IamInstanceProfile: { Name: NAMES.instanceProfileName }, UserData: readFileSync( join(RESOURCES_PATH, "server_startup_script.sh"), ).toString("base64"), KeyName: NAMES.keyPairName, }, }), ); }), new ScenarioOutput( "createdLaunchTemplate", MESSAGES.createdLaunchTemplate.replace( "${LAUNCH_TEMPLATE_NAME}", NAMES.launchTemplateName, ), ), new ScenarioOutput( "creatingAutoScalingGroup", MESSAGES.creatingAutoScalingGroup.replace( "${AUTO_SCALING_GROUP_NAME}", NAMES.autoScalingGroupName, ), ), new ScenarioAction("createAutoScalingGroup", async (state) => { const ec2Client = new EC2Client({}); const { AvailabilityZones } = await ec2Client.send( new DescribeAvailabilityZonesCommand({}), ); state.availabilityZoneNames = AvailabilityZones.map((az) => az.ZoneName); const autoScalingClient = new AutoScalingClient({}); await retry({ intervalInMs: 1000, maxRetries: 30 }, () => autoScalingClient.send( new CreateAutoScalingGroupCommand({ AvailabilityZones: state.availabilityZoneNames, AutoScalingGroupName: NAMES.autoScalingGroupName, LaunchTemplate: { LaunchTemplateName: NAMES.launchTemplateName, Version: "$Default", }, MinSize: 3, MaxSize: 3, }), ), ); }), new ScenarioOutput( "createdAutoScalingGroup", /** * @param {{ availabilityZoneNames: string[] }} state */ (state) => MESSAGES.createdAutoScalingGroup .replace("${AUTO_SCALING_GROUP_NAME}", NAMES.autoScalingGroupName) .replace( "${AVAILABILITY_ZONE_NAMES}", state.availabilityZoneNames.join(", "), ), ), new ScenarioInput("confirmContinue", MESSAGES.confirmContinue, { type: "confirm", }), new ScenarioOutput("loadBalancer", MESSAGES.loadBalancer), new ScenarioOutput("gettingVpc", MESSAGES.gettingVpc), new ScenarioAction("getVpc", async (state) => { const client = new EC2Client({}); const { Vpcs } = await client.send( new DescribeVpcsCommand({ Filters: [{ Name: "is-default", Values: ["true"] }], }), ); state.defaultVpc = Vpcs[0].VpcId; }), new ScenarioOutput("gotVpc", (state) => MESSAGES.gotVpc.replace("${VPC_ID}", state.defaultVpc), ), new ScenarioOutput("gettingSubnets", MESSAGES.gettingSubnets), new ScenarioAction("getSubnets", async (state) => { const client = new EC2Client({}); const { Subnets } = await client.send( new DescribeSubnetsCommand({ Filters: [ { Name: "vpc-id", Values: [state.defaultVpc] }, { Name: "availability-zone", Values: state.availabilityZoneNames }, { Name: "default-for-az", Values: ["true"] }, ], }), ); state.subnets = Subnets.map((subnet) => subnet.SubnetId); }), new ScenarioOutput( "gotSubnets", /** * @param {{ subnets: string[] }} state */ (state) => MESSAGES.gotSubnets.replace("${SUBNETS}", state.subnets.join(", ")), ), new ScenarioOutput( "creatingLoadBalancerTargetGroup", MESSAGES.creatingLoadBalancerTargetGroup.replace( "${TARGET_GROUP_NAME}", NAMES.loadBalancerTargetGroupName, ), ), new ScenarioAction("createLoadBalancerTargetGroup", async (state) => { const client = new ElasticLoadBalancingV2Client({}); const { TargetGroups } = await client.send( new CreateTargetGroupCommand({ Name: NAMES.loadBalancerTargetGroupName, Protocol: "HTTP", Port: 80, HealthCheckPath: "/healthcheck", HealthCheckIntervalSeconds: 10, HealthCheckTimeoutSeconds: 5, HealthyThresholdCount: 2, UnhealthyThresholdCount: 2, VpcId: state.defaultVpc, }), ); const targetGroup = TargetGroups[0]; state.targetGroupArn = targetGroup.TargetGroupArn; state.targetGroupProtocol = targetGroup.Protocol; state.targetGroupPort = targetGroup.Port; }), new ScenarioOutput( "createdLoadBalancerTargetGroup", MESSAGES.createdLoadBalancerTargetGroup.replace( "${TARGET_GROUP_NAME}", NAMES.loadBalancerTargetGroupName, ), ), new ScenarioOutput( "creatingLoadBalancer", MESSAGES.creatingLoadBalancer.replace("${LB_NAME}", NAMES.loadBalancerName), ), new ScenarioAction("createLoadBalancer", async (state) => { const client = new ElasticLoadBalancingV2Client({}); const { LoadBalancers } = await client.send( new CreateLoadBalancerCommand({ Name: NAMES.loadBalancerName, Subnets: state.subnets, }), ); state.loadBalancerDns = LoadBalancers[0].DNSName; state.loadBalancerArn = LoadBalancers[0].LoadBalancerArn; await waitUntilLoadBalancerAvailable( { client }, { Names: [NAMES.loadBalancerName] }, ); }), new ScenarioOutput("createdLoadBalancer", (state) => MESSAGES.createdLoadBalancer .replace("${LB_NAME}", NAMES.loadBalancerName) .replace("${DNS_NAME}", state.loadBalancerDns), ), new ScenarioOutput( "creatingListener", MESSAGES.creatingLoadBalancerListener .replace("${LB_NAME}", NAMES.loadBalancerName) .replace("${TARGET_GROUP_NAME}", NAMES.loadBalancerTargetGroupName), ), new ScenarioAction("createListener", async (state) => { const client = new ElasticLoadBalancingV2Client({}); const { Listeners } = await client.send( new CreateListenerCommand({ LoadBalancerArn: state.loadBalancerArn, Protocol: state.targetGroupProtocol, Port: state.targetGroupPort, DefaultActions: [ { Type: "forward", TargetGroupArn: state.targetGroupArn }, ], }), ); const listener = Listeners[0]; state.loadBalancerListenerArn = listener.ListenerArn; }), new ScenarioOutput("createdListener", (state) => MESSAGES.createdLoadBalancerListener.replace( "${LB_LISTENER_ARN}", state.loadBalancerListenerArn, ), ), new ScenarioOutput( "attachingLoadBalancerTargetGroup", MESSAGES.attachingLoadBalancerTargetGroup .replace("${TARGET_GROUP_NAME}", NAMES.loadBalancerTargetGroupName) .replace("${AUTO_SCALING_GROUP_NAME}", NAMES.autoScalingGroupName), ), new ScenarioAction("attachLoadBalancerTargetGroup", async (state) => { const client = new AutoScalingClient({}); await client.send( new AttachLoadBalancerTargetGroupsCommand({ AutoScalingGroupName: NAMES.autoScalingGroupName, TargetGroupARNs: [state.targetGroupArn], }), ); }), new ScenarioOutput( "attachedLoadBalancerTargetGroup", MESSAGES.attachedLoadBalancerTargetGroup, ), new ScenarioOutput("verifyingInboundPort", MESSAGES.verifyingInboundPort), new ScenarioAction( "verifyInboundPort", /** * * @param {{ defaultSecurityGroup: import('@aws-sdk/client-ec2').SecurityGroup}} state */ async (state) => { const client = new EC2Client({}); const { SecurityGroups } = await client.send( new DescribeSecurityGroupsCommand({ Filters: [{ Name: "group-name", Values: ["default"] }], }), ); if (!SecurityGroups) { state.verifyInboundPortError = new Error(MESSAGES.noSecurityGroups); } state.defaultSecurityGroup = SecurityGroups[0]; /** * @type {string} */ const ipResponse = (await axios.get("http://checkip.amazonaws.com")).data; state.myIp = ipResponse.trim(); const myIpRules = state.defaultSecurityGroup.IpPermissions.filter( ({ IpRanges }) => IpRanges.some( ({ CidrIp }) => CidrIp.startsWith(state.myIp) || CidrIp === "0.0.0.0/0", ), ) .filter(({ IpProtocol }) => IpProtocol === "tcp") .filter(({ FromPort }) => FromPort === 80); state.myIpRules = myIpRules; }, ), new ScenarioOutput( "verifiedInboundPort", /** * @param {{ myIpRules: any[] }} state */ (state) => { if (state.myIpRules.length > 0) { return MESSAGES.foundIpRules.replace( "${IP_RULES}", JSON.stringify(state.myIpRules, null, 2), ); } return MESSAGES.noIpRules; }, ), new ScenarioInput( "shouldAddInboundRule", /** * @param {{ myIpRules: any[] }} state */ (state) => { if (state.myIpRules.length > 0) { return false; } return MESSAGES.noIpRules; }, { type: "confirm" }, ), new ScenarioAction( "addInboundRule", /** * @param {{ defaultSecurityGroup: import('@aws-sdk/client-ec2').SecurityGroup }} state */ async (state) => { if (!state.shouldAddInboundRule) { return; } const client = new EC2Client({}); await client.send( new AuthorizeSecurityGroupIngressCommand({ GroupId: state.defaultSecurityGroup.GroupId, CidrIp: `${state.myIp}/32`, FromPort: 80, ToPort: 80, IpProtocol: "tcp", }), ); }, ), new ScenarioOutput("addedInboundRule", (state) => { if (state.shouldAddInboundRule) { return MESSAGES.addedInboundRule.replace("${IP_ADDRESS}", state.myIp); } return false; }), new ScenarioOutput("verifyingEndpoint", (state) => MESSAGES.verifyingEndpoint.replace("${DNS_NAME}", state.loadBalancerDns), ), new ScenarioAction("verifyEndpoint", async (state) => { try { const response = await retry({ intervalInMs: 2000, maxRetries: 30 }, () => axios.get(`http://${state.loadBalancerDns}`), ); state.endpointResponse = JSON.stringify(response.data, null, 2); } catch (e) { state.verifyEndpointError = e; } }), new ScenarioOutput("verifiedEndpoint", (state) => { if (state.verifyEndpointError) { console.error(state.verifyEndpointError); } else { return MESSAGES.verifiedEndpoint.replace( "${ENDPOINT_RESPONSE}", state.endpointResponse, ); } }), saveState, ];
Crea i passaggi per eseguire la demo.
import { readFileSync } from "node:fs"; import { join } from "node:path"; import axios from "axios"; import { DescribeTargetGroupsCommand, DescribeTargetHealthCommand, ElasticLoadBalancingV2Client, } from "@aws-sdk/client-elastic-load-balancing-v2"; import { DescribeInstanceInformationCommand, PutParameterCommand, SSMClient, SendCommandCommand, } from "@aws-sdk/client-ssm"; import { IAMClient, CreatePolicyCommand, CreateRoleCommand, AttachRolePolicyCommand, CreateInstanceProfileCommand, AddRoleToInstanceProfileCommand, waitUntilInstanceProfileExists, } from "@aws-sdk/client-iam"; import { AutoScalingClient, DescribeAutoScalingGroupsCommand, TerminateInstanceInAutoScalingGroupCommand, } from "@aws-sdk/client-auto-scaling"; import { DescribeIamInstanceProfileAssociationsCommand, EC2Client, RebootInstancesCommand, ReplaceIamInstanceProfileAssociationCommand, } from "@aws-sdk/client-ec2"; import { ScenarioAction, ScenarioInput, ScenarioOutput, } from "@aws-doc-sdk-examples/lib/scenario/scenario.js"; import { retry } from "@aws-doc-sdk-examples/lib/utils/util-timers.js"; import { MESSAGES, NAMES, RESOURCES_PATH } from "./constants.js"; import { findLoadBalancer } from "./shared.js"; const getRecommendation = new ScenarioAction( "getRecommendation", async (state) => { const loadBalancer = await findLoadBalancer(NAMES.loadBalancerName); if (loadBalancer) { state.loadBalancerDnsName = loadBalancer.DNSName; try { state.recommendation = ( await axios.get(`http://${state.loadBalancerDnsName}`) ).data; } catch (e) { state.recommendation = e instanceof Error ? e.message : e; } } else { throw new Error(MESSAGES.demoFindLoadBalancerError); } }, ); const getRecommendationResult = new ScenarioOutput( "getRecommendationResult", (state) => `Recommendation:\n${JSON.stringify(state.recommendation, null, 2)}`, { preformatted: true }, ); const getHealthCheck = new ScenarioAction("getHealthCheck", async (state) => { const client = new ElasticLoadBalancingV2Client({}); const { TargetGroups } = await client.send( new DescribeTargetGroupsCommand({ Names: [NAMES.loadBalancerTargetGroupName], }), ); const { TargetHealthDescriptions } = await client.send( new DescribeTargetHealthCommand({ TargetGroupArn: TargetGroups[0].TargetGroupArn, }), ); state.targetHealthDescriptions = TargetHealthDescriptions; }); const getHealthCheckResult = new ScenarioOutput( "getHealthCheckResult", /** * @param {{ targetHealthDescriptions: import('@aws-sdk/client-elastic-load-balancing-v2').TargetHealthDescription[]}} state */ (state) => { const status = state.targetHealthDescriptions .map((th) => `${th.Target.Id}: ${th.TargetHealth.State}`) .join("\n"); return `Health check:\n${status}`; }, { preformatted: true }, ); const loadBalancerLoop = new ScenarioAction( "loadBalancerLoop", getRecommendation.action, { whileConfig: { whileFn: ({ loadBalancerCheck }) => loadBalancerCheck, input: new ScenarioInput( "loadBalancerCheck", MESSAGES.demoLoadBalancerCheck, { type: "confirm", }, ), output: getRecommendationResult, }, }, ); const healthCheckLoop = new ScenarioAction( "healthCheckLoop", getHealthCheck.action, { whileConfig: { whileFn: ({ healthCheck }) => healthCheck, input: new ScenarioInput("healthCheck", MESSAGES.demoHealthCheck, { type: "confirm", }), output: getHealthCheckResult, }, }, ); const statusSteps = [ getRecommendation, getRecommendationResult, getHealthCheck, getHealthCheckResult, ]; /** * @type {import('@aws-doc-sdk-examples/lib/scenario.js').Step[]} */ export const demoSteps = [ new ScenarioOutput("header", MESSAGES.demoHeader, { header: true }), new ScenarioOutput("sanityCheck", MESSAGES.demoSanityCheck), ...statusSteps, new ScenarioInput( "brokenDependencyConfirmation", MESSAGES.demoBrokenDependencyConfirmation, { type: "confirm" }, ), new ScenarioAction("brokenDependency", async (state) => { if (!state.brokenDependencyConfirmation) { process.exit(); } else { const client = new SSMClient({}); state.badTableName = `fake-table-${Date.now()}`; await client.send( new PutParameterCommand({ Name: NAMES.ssmTableNameKey, Value: state.badTableName, Overwrite: true, Type: "String", }), ); } }), new ScenarioOutput("testBrokenDependency", (state) => MESSAGES.demoTestBrokenDependency.replace( "${TABLE_NAME}", state.badTableName, ), ), ...statusSteps, new ScenarioInput( "staticResponseConfirmation", MESSAGES.demoStaticResponseConfirmation, { type: "confirm" }, ), new ScenarioAction("staticResponse", async (state) => { if (!state.staticResponseConfirmation) { process.exit(); } else { const client = new SSMClient({}); await client.send( new PutParameterCommand({ Name: NAMES.ssmFailureResponseKey, Value: "static", Overwrite: true, Type: "String", }), ); } }), new ScenarioOutput("testStaticResponse", MESSAGES.demoTestStaticResponse), ...statusSteps, new ScenarioInput( "badCredentialsConfirmation", MESSAGES.demoBadCredentialsConfirmation, { type: "confirm" }, ), new ScenarioAction("badCredentialsExit", (state) => { if (!state.badCredentialsConfirmation) { process.exit(); } }), new ScenarioAction("fixDynamoDBName", async () => { const client = new SSMClient({}); await client.send( new PutParameterCommand({ Name: NAMES.ssmTableNameKey, Value: NAMES.tableName, Overwrite: true, Type: "String", }), ); }), new ScenarioAction( "badCredentials", /** * @param {{ targetInstance: import('@aws-sdk/client-auto-scaling').Instance }} state */ async (state) => { await createSsmOnlyInstanceProfile(); const autoScalingClient = new AutoScalingClient({}); const { AutoScalingGroups } = await autoScalingClient.send( new DescribeAutoScalingGroupsCommand({ AutoScalingGroupNames: [NAMES.autoScalingGroupName], }), ); state.targetInstance = AutoScalingGroups[0].Instances[0]; const ec2Client = new EC2Client({}); const { IamInstanceProfileAssociations } = await ec2Client.send( new DescribeIamInstanceProfileAssociationsCommand({ Filters: [ { Name: "instance-id", Values: [state.targetInstance.InstanceId] }, ], }), ); state.instanceProfileAssociationId = IamInstanceProfileAssociations[0].AssociationId; await retry({ intervalInMs: 1000, maxRetries: 30 }, () => ec2Client.send( new ReplaceIamInstanceProfileAssociationCommand({ AssociationId: state.instanceProfileAssociationId, IamInstanceProfile: { Name: NAMES.ssmOnlyInstanceProfileName }, }), ), ); await ec2Client.send( new RebootInstancesCommand({ InstanceIds: [state.targetInstance.InstanceId], }), ); const ssmClient = new SSMClient({}); await retry({ intervalInMs: 20000, maxRetries: 15 }, async () => { const { InstanceInformationList } = await ssmClient.send( new DescribeInstanceInformationCommand({}), ); const instance = InstanceInformationList.find( (info) => info.InstanceId === state.targetInstance.InstanceId, ); if (!instance) { throw new Error("Instance not found."); } }); await ssmClient.send( new SendCommandCommand({ InstanceIds: [state.targetInstance.InstanceId], DocumentName: "AWS-RunShellScript", Parameters: { commands: ["cd / && sudo python3 server.py 80"] }, }), ); }, ), new ScenarioOutput( "testBadCredentials", /** * @param {{ targetInstance: import('@aws-sdk/client-ssm').InstanceInformation}} state */ (state) => MESSAGES.demoTestBadCredentials.replace( "${INSTANCE_ID}", state.targetInstance.InstanceId, ), ), loadBalancerLoop, new ScenarioInput( "deepHealthCheckConfirmation", MESSAGES.demoDeepHealthCheckConfirmation, { type: "confirm" }, ), new ScenarioAction("deepHealthCheckExit", (state) => { if (!state.deepHealthCheckConfirmation) { process.exit(); } }), new ScenarioAction("deepHealthCheck", async () => { const client = new SSMClient({}); await client.send( new PutParameterCommand({ Name: NAMES.ssmHealthCheckKey, Value: "deep", Overwrite: true, Type: "String", }), ); }), new ScenarioOutput("testDeepHealthCheck", MESSAGES.demoTestDeepHealthCheck), healthCheckLoop, loadBalancerLoop, new ScenarioInput( "killInstanceConfirmation", /** * @param {{ targetInstance: import('@aws-sdk/client-ssm').InstanceInformation }} state */ (state) => MESSAGES.demoKillInstanceConfirmation.replace( "${INSTANCE_ID}", state.targetInstance.InstanceId, ), { type: "confirm" }, ), new ScenarioAction("killInstanceExit", (state) => { if (!state.killInstanceConfirmation) { process.exit(); } }), new ScenarioAction( "killInstance", /** * @param {{ targetInstance: import('@aws-sdk/client-ssm').InstanceInformation }} state */ async (state) => { const client = new AutoScalingClient({}); await client.send( new TerminateInstanceInAutoScalingGroupCommand({ InstanceId: state.targetInstance.InstanceId, ShouldDecrementDesiredCapacity: false, }), ); }, ), new ScenarioOutput("testKillInstance", MESSAGES.demoTestKillInstance), healthCheckLoop, loadBalancerLoop, new ScenarioInput("failOpenConfirmation", MESSAGES.demoFailOpenConfirmation, { type: "confirm", }), new ScenarioAction("failOpenExit", (state) => { if (!state.failOpenConfirmation) { process.exit(); } }), new ScenarioAction("failOpen", () => { const client = new SSMClient({}); return client.send( new PutParameterCommand({ Name: NAMES.ssmTableNameKey, Value: `fake-table-${Date.now()}`, Overwrite: true, Type: "String", }), ); }), new ScenarioOutput("testFailOpen", MESSAGES.demoFailOpenTest), healthCheckLoop, loadBalancerLoop, new ScenarioInput( "resetTableConfirmation", MESSAGES.demoResetTableConfirmation, { type: "confirm" }, ), new ScenarioAction("resetTableExit", (state) => { if (!state.resetTableConfirmation) { process.exit(); } }), new ScenarioAction("resetTable", async () => { const client = new SSMClient({}); await client.send( new PutParameterCommand({ Name: NAMES.ssmTableNameKey, Value: NAMES.tableName, Overwrite: true, Type: "String", }), ); }), new ScenarioOutput("testResetTable", MESSAGES.demoTestResetTable), healthCheckLoop, loadBalancerLoop, ]; async function createSsmOnlyInstanceProfile() { const iamClient = new IAMClient({}); const { Policy } = await iamClient.send( new CreatePolicyCommand({ PolicyName: NAMES.ssmOnlyPolicyName, PolicyDocument: readFileSync( join(RESOURCES_PATH, "ssm_only_policy.json"), ), }), ); await iamClient.send( new CreateRoleCommand({ RoleName: NAMES.ssmOnlyRoleName, AssumeRolePolicyDocument: JSON.stringify({ Version: "2012-10-17", Statement: [ { Effect: "Allow", Principal: { Service: "ec2.amazonaws.com" }, Action: "sts:AssumeRole", }, ], }), }), ); await iamClient.send( new AttachRolePolicyCommand({ RoleName: NAMES.ssmOnlyRoleName, PolicyArn: Policy.Arn, }), ); await iamClient.send( new AttachRolePolicyCommand({ RoleName: NAMES.ssmOnlyRoleName, PolicyArn: "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore", }), ); const { InstanceProfile } = await iamClient.send( new CreateInstanceProfileCommand({ InstanceProfileName: NAMES.ssmOnlyInstanceProfileName, }), ); await waitUntilInstanceProfileExists( { client: iamClient }, { InstanceProfileName: NAMES.ssmOnlyInstanceProfileName }, ); await iamClient.send( new AddRoleToInstanceProfileCommand({ InstanceProfileName: NAMES.ssmOnlyInstanceProfileName, RoleName: NAMES.ssmOnlyRoleName, }), ); return InstanceProfile; }
Crea i passaggi per distruggere tutte le risorse.
import { unlinkSync } from "node:fs"; import { DynamoDBClient, DeleteTableCommand } from "@aws-sdk/client-dynamodb"; import { EC2Client, DeleteKeyPairCommand, DeleteLaunchTemplateCommand, RevokeSecurityGroupIngressCommand, } from "@aws-sdk/client-ec2"; import { IAMClient, DeleteInstanceProfileCommand, RemoveRoleFromInstanceProfileCommand, DeletePolicyCommand, DeleteRoleCommand, DetachRolePolicyCommand, paginateListPolicies, } from "@aws-sdk/client-iam"; import { AutoScalingClient, DeleteAutoScalingGroupCommand, TerminateInstanceInAutoScalingGroupCommand, UpdateAutoScalingGroupCommand, paginateDescribeAutoScalingGroups, } from "@aws-sdk/client-auto-scaling"; import { DeleteLoadBalancerCommand, DeleteTargetGroupCommand, DescribeTargetGroupsCommand, ElasticLoadBalancingV2Client, } from "@aws-sdk/client-elastic-load-balancing-v2"; import { ScenarioOutput, ScenarioInput, ScenarioAction, } from "@aws-doc-sdk-examples/lib/scenario/index.js"; import { loadState } from "@aws-doc-sdk-examples/lib/scenario/steps-common.js"; import { retry } from "@aws-doc-sdk-examples/lib/utils/util-timers.js"; import { MESSAGES, NAMES } from "./constants.js"; import { findLoadBalancer } from "./shared.js"; /** * @type {import('@aws-doc-sdk-examples/lib/scenario.js').Step[]} */ export const destroySteps = [ loadState, new ScenarioInput("destroy", MESSAGES.destroy, { type: "confirm" }), new ScenarioAction( "abort", (state) => state.destroy === false && process.exit(), ), new ScenarioAction("deleteTable", async (c) => { try { const client = new DynamoDBClient({}); await client.send(new DeleteTableCommand({ TableName: NAMES.tableName })); } catch (e) { c.deleteTableError = e; } }), new ScenarioOutput("deleteTableResult", (state) => { if (state.deleteTableError) { console.error(state.deleteTableError); return MESSAGES.deleteTableError.replace( "${TABLE_NAME}", NAMES.tableName, ); } return MESSAGES.deletedTable.replace("${TABLE_NAME}", NAMES.tableName); }), new ScenarioAction("deleteKeyPair", async (state) => { try { const client = new EC2Client({}); await client.send( new DeleteKeyPairCommand({ KeyName: NAMES.keyPairName }), ); unlinkSync(`${NAMES.keyPairName}.pem`); } catch (e) { state.deleteKeyPairError = e; } }), new ScenarioOutput("deleteKeyPairResult", (state) => { if (state.deleteKeyPairError) { console.error(state.deleteKeyPairError); return MESSAGES.deleteKeyPairError.replace( "${KEY_PAIR_NAME}", NAMES.keyPairName, ); } return MESSAGES.deletedKeyPair.replace( "${KEY_PAIR_NAME}", NAMES.keyPairName, ); }), new ScenarioAction("detachPolicyFromRole", async (state) => { try { const client = new IAMClient({}); const policy = await findPolicy(NAMES.instancePolicyName); if (!policy) { state.detachPolicyFromRoleError = new Error( `Policy ${NAMES.instancePolicyName} not found.`, ); } else { await client.send( new DetachRolePolicyCommand({ RoleName: NAMES.instanceRoleName, PolicyArn: policy.Arn, }), ); } } catch (e) { state.detachPolicyFromRoleError = e; } }), new ScenarioOutput("detachedPolicyFromRole", (state) => { if (state.detachPolicyFromRoleError) { console.error(state.detachPolicyFromRoleError); return MESSAGES.detachPolicyFromRoleError .replace("${INSTANCE_POLICY_NAME}", NAMES.instancePolicyName) .replace("${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName); } return MESSAGES.detachedPolicyFromRole .replace("${INSTANCE_POLICY_NAME}", NAMES.instancePolicyName) .replace("${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName); }), new ScenarioAction("deleteInstancePolicy", async (state) => { const client = new IAMClient({}); const policy = await findPolicy(NAMES.instancePolicyName); if (!policy) { state.deletePolicyError = new Error( `Policy ${NAMES.instancePolicyName} not found.`, ); } else { return client.send( new DeletePolicyCommand({ PolicyArn: policy.Arn, }), ); } }), new ScenarioOutput("deletePolicyResult", (state) => { if (state.deletePolicyError) { console.error(state.deletePolicyError); return MESSAGES.deletePolicyError.replace( "${INSTANCE_POLICY_NAME}", NAMES.instancePolicyName, ); } return MESSAGES.deletedPolicy.replace( "${INSTANCE_POLICY_NAME}", NAMES.instancePolicyName, ); }), new ScenarioAction("removeRoleFromInstanceProfile", async (state) => { try { const client = new IAMClient({}); await client.send( new RemoveRoleFromInstanceProfileCommand({ RoleName: NAMES.instanceRoleName, InstanceProfileName: NAMES.instanceProfileName, }), ); } catch (e) { state.removeRoleFromInstanceProfileError = e; } }), new ScenarioOutput("removeRoleFromInstanceProfileResult", (state) => { if (state.removeRoleFromInstanceProfile) { console.error(state.removeRoleFromInstanceProfileError); return MESSAGES.removeRoleFromInstanceProfileError .replace("${INSTANCE_PROFILE_NAME}", NAMES.instanceProfileName) .replace("${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName); } return MESSAGES.removedRoleFromInstanceProfile .replace("${INSTANCE_PROFILE_NAME}", NAMES.instanceProfileName) .replace("${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName); }), new ScenarioAction("deleteInstanceRole", async (state) => { try { const client = new IAMClient({}); await client.send( new DeleteRoleCommand({ RoleName: NAMES.instanceRoleName, }), ); } catch (e) { state.deleteInstanceRoleError = e; } }), new ScenarioOutput("deleteInstanceRoleResult", (state) => { if (state.deleteInstanceRoleError) { console.error(state.deleteInstanceRoleError); return MESSAGES.deleteInstanceRoleError.replace( "${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName, ); } return MESSAGES.deletedInstanceRole.replace( "${INSTANCE_ROLE_NAME}", NAMES.instanceRoleName, ); }), new ScenarioAction("deleteInstanceProfile", async (state) => { try { const client = new IAMClient({}); await client.send( new DeleteInstanceProfileCommand({ InstanceProfileName: NAMES.instanceProfileName, }), ); } catch (e) { state.deleteInstanceProfileError = e; } }), new ScenarioOutput("deleteInstanceProfileResult", (state) => { if (state.deleteInstanceProfileError) { console.error(state.deleteInstanceProfileError); return MESSAGES.deleteInstanceProfileError.replace( "${INSTANCE_PROFILE_NAME}", NAMES.instanceProfileName, ); } return MESSAGES.deletedInstanceProfile.replace( "${INSTANCE_PROFILE_NAME}", NAMES.instanceProfileName, ); }), new ScenarioAction("deleteAutoScalingGroup", async (state) => { try { await terminateGroupInstances(NAMES.autoScalingGroupName); await retry({ intervalInMs: 60000, maxRetries: 60 }, async () => { await deleteAutoScalingGroup(NAMES.autoScalingGroupName); }); } catch (e) { state.deleteAutoScalingGroupError = e; } }), new ScenarioOutput("deleteAutoScalingGroupResult", (state) => { if (state.deleteAutoScalingGroupError) { console.error(state.deleteAutoScalingGroupError); return MESSAGES.deleteAutoScalingGroupError.replace( "${AUTO_SCALING_GROUP_NAME}", NAMES.autoScalingGroupName, ); } return MESSAGES.deletedAutoScalingGroup.replace( "${AUTO_SCALING_GROUP_NAME}", NAMES.autoScalingGroupName, ); }), new ScenarioAction("deleteLaunchTemplate", async (state) => { const client = new EC2Client({}); try { await client.send( new DeleteLaunchTemplateCommand({ LaunchTemplateName: NAMES.launchTemplateName, }), ); } catch (e) { state.deleteLaunchTemplateError = e; } }), new ScenarioOutput("deleteLaunchTemplateResult", (state) => { if (state.deleteLaunchTemplateError) { console.error(state.deleteLaunchTemplateError); return MESSAGES.deleteLaunchTemplateError.replace( "${LAUNCH_TEMPLATE_NAME}", NAMES.launchTemplateName, ); } return MESSAGES.deletedLaunchTemplate.replace( "${LAUNCH_TEMPLATE_NAME}", NAMES.launchTemplateName, ); }), new ScenarioAction("deleteLoadBalancer", async (state) => { try { const client = new ElasticLoadBalancingV2Client({}); const loadBalancer = await findLoadBalancer(NAMES.loadBalancerName); await client.send( new DeleteLoadBalancerCommand({ LoadBalancerArn: loadBalancer.LoadBalancerArn, }), ); await retry({ intervalInMs: 1000, maxRetries: 60 }, async () => { const lb = await findLoadBalancer(NAMES.loadBalancerName); if (lb) { throw new Error("Load balancer still exists."); } }); } catch (e) { state.deleteLoadBalancerError = e; } }), new ScenarioOutput("deleteLoadBalancerResult", (state) => { if (state.deleteLoadBalancerError) { console.error(state.deleteLoadBalancerError); return MESSAGES.deleteLoadBalancerError.replace( "${LB_NAME}", NAMES.loadBalancerName, ); } return MESSAGES.deletedLoadBalancer.replace( "${LB_NAME}", NAMES.loadBalancerName, ); }), new ScenarioAction("deleteLoadBalancerTargetGroup", async (state) => { const client = new ElasticLoadBalancingV2Client({}); try { const { TargetGroups } = await client.send( new DescribeTargetGroupsCommand({ Names: [NAMES.loadBalancerTargetGroupName], }), ); await retry({ intervalInMs: 1000, maxRetries: 30 }, () => client.send( new DeleteTargetGroupCommand({ TargetGroupArn: TargetGroups[0].TargetGroupArn, }), ), ); } catch (e) { state.deleteLoadBalancerTargetGroupError = e; } }), new ScenarioOutput("deleteLoadBalancerTargetGroupResult", (state) => { if (state.deleteLoadBalancerTargetGroupError) { console.error(state.deleteLoadBalancerTargetGroupError); return MESSAGES.deleteLoadBalancerTargetGroupError.replace( "${TARGET_GROUP_NAME}", NAMES.loadBalancerTargetGroupName, ); } return MESSAGES.deletedLoadBalancerTargetGroup.replace( "${TARGET_GROUP_NAME}", NAMES.loadBalancerTargetGroupName, ); }), new ScenarioAction("detachSsmOnlyRoleFromProfile", async (state) => { try { const client = new IAMClient({}); await client.send( new RemoveRoleFromInstanceProfileCommand({ InstanceProfileName: NAMES.ssmOnlyInstanceProfileName, RoleName: NAMES.ssmOnlyRoleName, }), ); } catch (e) { state.detachSsmOnlyRoleFromProfileError = e; } }), new ScenarioOutput("detachSsmOnlyRoleFromProfileResult", (state) => { if (state.detachSsmOnlyRoleFromProfileError) { console.error(state.detachSsmOnlyRoleFromProfileError); return MESSAGES.detachSsmOnlyRoleFromProfileError .replace("${ROLE_NAME}", NAMES.ssmOnlyRoleName) .replace("${PROFILE_NAME}", NAMES.ssmOnlyInstanceProfileName); } return MESSAGES.detachedSsmOnlyRoleFromProfile .replace("${ROLE_NAME}", NAMES.ssmOnlyRoleName) .replace("${PROFILE_NAME}", NAMES.ssmOnlyInstanceProfileName); }), new ScenarioAction("detachSsmOnlyCustomRolePolicy", async (state) => { try { const iamClient = new IAMClient({}); const ssmOnlyPolicy = await findPolicy(NAMES.ssmOnlyPolicyName); await iamClient.send( new DetachRolePolicyCommand({ RoleName: NAMES.ssmOnlyRoleName, PolicyArn: ssmOnlyPolicy.Arn, }), ); } catch (e) { state.detachSsmOnlyCustomRolePolicyError = e; } }), new ScenarioOutput("detachSsmOnlyCustomRolePolicyResult", (state) => { if (state.detachSsmOnlyCustomRolePolicyError) { console.error(state.detachSsmOnlyCustomRolePolicyError); return MESSAGES.detachSsmOnlyCustomRolePolicyError .replace("${ROLE_NAME}", NAMES.ssmOnlyRoleName) .replace("${POLICY_NAME}", NAMES.ssmOnlyPolicyName); } return MESSAGES.detachedSsmOnlyCustomRolePolicy .replace("${ROLE_NAME}", NAMES.ssmOnlyRoleName) .replace("${POLICY_NAME}", NAMES.ssmOnlyPolicyName); }), new ScenarioAction("detachSsmOnlyAWSRolePolicy", async (state) => { try { const iamClient = new IAMClient({}); await iamClient.send( new DetachRolePolicyCommand({ RoleName: NAMES.ssmOnlyRoleName, PolicyArn: "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore", }), ); } catch (e) { state.detachSsmOnlyAWSRolePolicyError = e; } }), new ScenarioOutput("detachSsmOnlyAWSRolePolicyResult", (state) => { if (state.detachSsmOnlyAWSRolePolicyError) { console.error(state.detachSsmOnlyAWSRolePolicyError); return MESSAGES.detachSsmOnlyAWSRolePolicyError .replace("${ROLE_NAME}", NAMES.ssmOnlyRoleName) .replace("${POLICY_NAME}", "AmazonSSMManagedInstanceCore"); } return MESSAGES.detachedSsmOnlyAWSRolePolicy .replace("${ROLE_NAME}", NAMES.ssmOnlyRoleName) .replace("${POLICY_NAME}", "AmazonSSMManagedInstanceCore"); }), new ScenarioAction("deleteSsmOnlyInstanceProfile", async (state) => { try { const iamClient = new IAMClient({}); await iamClient.send( new DeleteInstanceProfileCommand({ InstanceProfileName: NAMES.ssmOnlyInstanceProfileName, }), ); } catch (e) { state.deleteSsmOnlyInstanceProfileError = e; } }), new ScenarioOutput("deleteSsmOnlyInstanceProfileResult", (state) => { if (state.deleteSsmOnlyInstanceProfileError) { console.error(state.deleteSsmOnlyInstanceProfileError); return MESSAGES.deleteSsmOnlyInstanceProfileError.replace( "${INSTANCE_PROFILE_NAME}", NAMES.ssmOnlyInstanceProfileName, ); } return MESSAGES.deletedSsmOnlyInstanceProfile.replace( "${INSTANCE_PROFILE_NAME}", NAMES.ssmOnlyInstanceProfileName, ); }), new ScenarioAction("deleteSsmOnlyPolicy", async (state) => { try { const iamClient = new IAMClient({}); const ssmOnlyPolicy = await findPolicy(NAMES.ssmOnlyPolicyName); await iamClient.send( new DeletePolicyCommand({ PolicyArn: ssmOnlyPolicy.Arn, }), ); } catch (e) { state.deleteSsmOnlyPolicyError = e; } }), new ScenarioOutput("deleteSsmOnlyPolicyResult", (state) => { if (state.deleteSsmOnlyPolicyError) { console.error(state.deleteSsmOnlyPolicyError); return MESSAGES.deleteSsmOnlyPolicyError.replace( "${POLICY_NAME}", NAMES.ssmOnlyPolicyName, ); } return MESSAGES.deletedSsmOnlyPolicy.replace( "${POLICY_NAME}", NAMES.ssmOnlyPolicyName, ); }), new ScenarioAction("deleteSsmOnlyRole", async (state) => { try { const iamClient = new IAMClient({}); await iamClient.send( new DeleteRoleCommand({ RoleName: NAMES.ssmOnlyRoleName, }), ); } catch (e) { state.deleteSsmOnlyRoleError = e; } }), new ScenarioOutput("deleteSsmOnlyRoleResult", (state) => { if (state.deleteSsmOnlyRoleError) { console.error(state.deleteSsmOnlyRoleError); return MESSAGES.deleteSsmOnlyRoleError.replace( "${ROLE_NAME}", NAMES.ssmOnlyRoleName, ); } return MESSAGES.deletedSsmOnlyRole.replace( "${ROLE_NAME}", NAMES.ssmOnlyRoleName, ); }), new ScenarioAction( "revokeSecurityGroupIngress", async ( /** @type {{ myIp: string, defaultSecurityGroup: { GroupId: string } }} */ state, ) => { const ec2Client = new EC2Client({}); try { await ec2Client.send( new RevokeSecurityGroupIngressCommand({ GroupId: state.defaultSecurityGroup.GroupId, CidrIp: `${state.myIp}/32`, FromPort: 80, ToPort: 80, IpProtocol: "tcp", }), ); } catch (e) { state.revokeSecurityGroupIngressError = e; } }, ), new ScenarioOutput("revokeSecurityGroupIngressResult", (state) => { if (state.revokeSecurityGroupIngressError) { console.error(state.revokeSecurityGroupIngressError); return MESSAGES.revokeSecurityGroupIngressError.replace( "${IP}", state.myIp, ); } return MESSAGES.revokedSecurityGroupIngress.replace("${IP}", state.myIp); }), ]; /** * @param {string} policyName */ async function findPolicy(policyName) { const client = new IAMClient({}); const paginatedPolicies = paginateListPolicies({ client }, {}); for await (const page of paginatedPolicies) { const policy = page.Policies.find((p) => p.PolicyName === policyName); if (policy) { return policy; } } } /** * @param {string} groupName */ async function deleteAutoScalingGroup(groupName) { const client = new AutoScalingClient({}); try { await client.send( new DeleteAutoScalingGroupCommand({ AutoScalingGroupName: groupName, }), ); } catch (err) { if (!(err instanceof Error)) { throw err; } console.log(err.name); throw err; } } /** * @param {string} groupName */ async function terminateGroupInstances(groupName) { const autoScalingClient = new AutoScalingClient({}); const group = await findAutoScalingGroup(groupName); await autoScalingClient.send( new UpdateAutoScalingGroupCommand({ AutoScalingGroupName: group.AutoScalingGroupName, MinSize: 0, }), ); for (const i of group.Instances) { await retry({ intervalInMs: 1000, maxRetries: 30 }, () => autoScalingClient.send( new TerminateInstanceInAutoScalingGroupCommand({ InstanceId: i.InstanceId, ShouldDecrementDesiredCapacity: true, }), ), ); } } async function findAutoScalingGroup(groupName) { const client = new AutoScalingClient({}); const paginatedGroups = paginateDescribeAutoScalingGroups({ client }, {}); for await (const page of paginatedGroups) { const group = page.AutoScalingGroups.find( (g) => g.AutoScalingGroupName === groupName, ); if (group) { return group; } } throw new Error(`Auto scaling group ${groupName} not found.`); }
-
Per API i dettagli, consulta i seguenti argomenti in AWS SDK for JavaScript APIRiferimento.
-