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à.
Elastic Load Balancing - Esempi della versione 2 con SDK for JavaScript (v3)
I seguenti esempi di codice mostrano come eseguire azioni e implementare scenari comuni utilizzando AWS SDK for JavaScript (v3) con Elastic Load Balancing - Version 2.
Le operazioni sono estratti di codice da programmi più grandi e devono essere eseguite nel contesto. Sebbene le azioni mostrino come richiamare le singole funzioni di servizio, è possibile visualizzare le azioni nel contesto negli scenari correlati.
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 utilizzare Elastic Load Balancing.
- 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 { ElasticLoadBalancingV2Client, DescribeLoadBalancersCommand, } from "@aws-sdk/client-elastic-load-balancing-v2"; export async function main() { const client = new ElasticLoadBalancingV2Client({}); const { LoadBalancers } = await client.send( new DescribeLoadBalancersCommand({}), ); const loadBalancersList = LoadBalancers.map( (lb) => `• ${lb.LoadBalancerName}: ${lb.DNSName}`, ).join("\n"); console.log( "Hello, Elastic Load Balancing! Let's list some of your load balancers:\n", loadBalancersList, ); } // Call function if run directly import { fileURLToPath } from "node:url"; if (process.argv[1] === fileURLToPath(import.meta.url)) { main(); }
-
Per API i dettagli, vedi DescribeLoadBalancers AWS SDK for JavaScriptAPIReference.
-
Azioni
Il seguente esempio di codice mostra come utilizzareCreateListener
.
- 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 ElasticLoadBalancingV2Client({}); const { Listeners } = await client.send( new CreateListenerCommand({ LoadBalancerArn: state.loadBalancerArn, Protocol: state.targetGroupProtocol, Port: state.targetGroupPort, DefaultActions: [ { Type: "forward", TargetGroupArn: state.targetGroupArn }, ], }), );
-
Per API i dettagli, vedi CreateListener AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareCreateLoadBalancer
.
- 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 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] }, );
-
Per API i dettagli, vedi CreateLoadBalancer AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareCreateTargetGroup
.
- 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 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, }), );
-
Per API i dettagli, vedi CreateTargetGroup AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDeleteLoadBalancer
.
- 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 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."); } });
-
Per API i dettagli, vedi DeleteLoadBalancer AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDeleteTargetGroup
.
- 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 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; }
-
Per API i dettagli, vedi DeleteTargetGroup AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeLoadBalancers
.
- 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 { ElasticLoadBalancingV2Client, DescribeLoadBalancersCommand, } from "@aws-sdk/client-elastic-load-balancing-v2"; export async function main() { const client = new ElasticLoadBalancingV2Client({}); const { LoadBalancers } = await client.send( new DescribeLoadBalancersCommand({}), ); const loadBalancersList = LoadBalancers.map( (lb) => `• ${lb.LoadBalancerName}: ${lb.DNSName}`, ).join("\n"); console.log( "Hello, Elastic Load Balancing! Let's list some of your load balancers:\n", loadBalancersList, ); } // Call function if run directly import { fileURLToPath } from "node:url"; if (process.argv[1] === fileURLToPath(import.meta.url)) { main(); }
-
Per API i dettagli, vedi DescribeLoadBalancers AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeTargetGroups
.
- 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 ElasticLoadBalancingV2Client({}); const { TargetGroups } = await client.send( new DescribeTargetGroupsCommand({ Names: [NAMES.loadBalancerTargetGroupName], }), );
-
Per API i dettagli, vedi DescribeTargetGroups AWS SDK for JavaScriptAPIReference.
-
Il seguente esempio di codice mostra come utilizzareDescribeTargetHealth
.
- 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 { TargetHealthDescriptions } = await client.send( new DescribeTargetHealthCommand({ TargetGroupArn: TargetGroups[0].TargetGroupArn, }), );
-
Per API i dettagli, vedi DescribeTargetHealth 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.
-