기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
Amazon EC2 인스턴스 시작
이 예제에서는를 사용하여 동일한 Amazon Machine Image(AMI)에서 하나 이상의 동일하게 구성된 Amazon EC2 인스턴스를 AWS SDK for .NET 시작하는 방법을 보여줍니다. 사용자가 제공하는 여러 입력을 사용하여 애플리케이션은 EC2 인스턴스를 시작한 다음 인스턴스가 '보류 중' 상태가 될 때까지 인스턴스를 모니터링합니다.
EC2 인스턴스가 실행 중일 때에 설명된 대로 원격으로 연결할 수 있습니다(선택 사항) 인스턴스에 연결.
주의
EC2-Classic은 2022년 8월 15일에 사용 중지되었습니다. EC2-Classic에서 VPC로 마이그레이션하는 것이 좋습니다. 자세한 내용은 EC2-Classic Networking is Retiring - 준비 방법을 참조하세요
다음 섹션에서는 이 예제의 코드 조각과 기타 정보를 제공합니다. 예제의 전체 코드는 코드 조각 뒤에 표시되며, 그대로 빌드하고 실행할 수 있습니다.
필요한 내용 수집
EC2 인스턴스를 시작하려면 몇 가지 사항이 필요합니다.
-
인스턴스가 시작될 VPC에 있는 기존 서브넷의 ID입니다. 이를 찾거나 생성하는 쉬운 방법은 Amazon VPC 콘솔
에 로그인하는 것이지만 Word CreateSubnetAsync 및 DescribeSubnetsAsync 메서드를 사용하여 프로그래밍 방식으로 얻을 수도 있습니다. 참고
이 파라미터를 제공하지 않으면 계정의 기본 VPC에서 새 인스턴스가 시작됩니다.
-
인스턴스가 시작될 VPC에 속하는 기존 보안 그룹의 ID입니다. 자세한 내용은 Amazon EC2에서 보안 그룹 작업 단원을 참조하십시오.
-
새 인스턴스에 연결하려면 앞서 언급한 보안 그룹에 포트 22(Linux 인스턴스)의 SSH 트래픽 또는 포트 3389(Windows 인스턴스)의 RDP 트래픽을 허용하는 적절한 인바운드 규칙이 있어야 합니다. 이를 수행하는 방법은 해당 주제의 끝 부분에 있는 추가 고려 사항을 포함하여 보안 그룹 업데이트을 참조하세요.
-
인스턴스를 생성하는 데 사용할 Amazon Machine Image(AMI)입니다. AMIs에 대한 자세한 내용은 Amazon Word 사용 설명서의 Amazon Machine Images(AMIs)를 참조하세요. EC2 특히 AMI 찾기 및 공유 AMIs를 참조하세요.
-
새 인스턴스에 연결하는 데 사용되는 기존 EC2 키 페어의 이름입니다. 자세한 내용은 Amazon EC2 키 페어 작업 단원을 참조하십시오.
-
앞서 언급한 PEM 키 페어의 프라이빗 키가 포함된 EC2 파일의 이름입니다. PEM 파일은 인스턴스에 원격으로 연결할 때 사용됩니다.
인스턴스 시작
다음 코드 조각은 EC2 인스턴스를 시작합니다.
이 주제의 끝 부분에 있는 예제에서는 사용 중인 이 코드 조각을 보여줍니다.
// // Method to launch the instances // Returns a list with the launched instance IDs private static async Task<List<string>> LaunchInstances( IAmazonEC2 ec2Client, RunInstancesRequest requestLaunch) { var instanceIds = new List<string>(); RunInstancesResponse responseLaunch = await ec2Client.RunInstancesAsync(requestLaunch); Console.WriteLine("\nNew instances have been created."); foreach (Instance item in responseLaunch.Reservation.Instances) { instanceIds.Add(item.InstanceId); Console.WriteLine($" New instance: {item.InstanceId}"); } return instanceIds; }
인스턴스 모니터링
다음 코드 조각은 “Pending” 상태가 아닐 때까지 인스턴스를 모니터링합니다.
이 주제의 끝 부분에 있는 예제에서는 사용 중인 이 코드 조각을 보여줍니다.
Instance.State.Code
속성의 유효한 값은 InstanceState 클래스를 참조하세요.
// // Method to wait until the instances are running (or at least not pending) private static async Task CheckState(IAmazonEC2 ec2Client, List<string> instanceIds) { Console.WriteLine( "\nWaiting for the instances to start." + "\nPress any key to stop waiting. (Response might be slightly delayed.)"); int numberRunning; DescribeInstancesResponse responseDescribe; var requestDescribe = new DescribeInstancesRequest{ InstanceIds = instanceIds}; // Check every couple of seconds int wait = 2000; while(true) { // Get and check the status for each of the instances to see if it's past pending. // Once all instances are past pending, break out. // (For this example, we are assuming that there is only one reservation.) Console.Write("."); numberRunning = 0; responseDescribe = await ec2Client.DescribeInstancesAsync(requestDescribe); foreach(Instance i in responseDescribe.Reservations[0].Instances) { // Check the lower byte of State.Code property // Code == 0 is the pending state if((i.State.Code & 255) > 0) numberRunning++; } if(numberRunning == responseDescribe.Reservations[0].Instances.Count) break; // Wait a bit and try again (unless the user wants to stop waiting) Thread.Sleep(wait); if(Console.KeyAvailable) break; } Console.WriteLine("\nNo more instances are pending."); foreach(Instance i in responseDescribe.Reservations[0].Instances) { Console.WriteLine($"For {i.InstanceId}:"); Console.WriteLine($" VPC ID: {i.VpcId}"); Console.WriteLine($" Instance state: {i.State.Name}"); Console.WriteLine($" Public IP address: {i.PublicIpAddress}"); Console.WriteLine($" Public DNS name: {i.PublicDnsName}"); Console.WriteLine($" Key pair name: {i.KeyName}"); } }
전체 코드
이 섹션에는 이 예제에 대한 관련 참조와 전체 코드가 나와 있습니다.
NuGet 패키지:
프로그래밍 요소:
-
네임스페이스 Amazon.EC2
클래스 AmazonEC2Client
클래스 InstanceType
-
네임스페이스 Amazon.EC2.모델
클래스 Instance
using System; using System.Threading; using System.Threading.Tasks; using System.Collections.Generic; using Amazon.EC2; using Amazon.EC2.Model; namespace EC2LaunchInstance { // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // Class to launch an EC2 instance class Program { static async Task Main(string[] args) { // Parse the command line and show help if necessary var parsedArgs = CommandLine.Parse(args); if(parsedArgs.Count == 0) { PrintHelp(); return; } // Get the application arguments from the parsed list string groupID = CommandLine.GetArgument(parsedArgs, null, "-g", "--group-id"); string ami = CommandLine.GetArgument(parsedArgs, null, "-a", "--ami-id"); string keyPairName = CommandLine.GetArgument(parsedArgs, null, "-k", "--keypair-name"); string subnetID = CommandLine.GetArgument(parsedArgs, null, "-s", "--subnet-id"); if( (string.IsNullOrEmpty(groupID) || !groupID.StartsWith("sg-")) || (string.IsNullOrEmpty(ami) || !ami.StartsWith("ami-")) || (string.IsNullOrEmpty(keyPairName)) || (!string.IsNullOrEmpty(subnetID) && !subnetID.StartsWith("subnet-"))) CommandLine.ErrorExit( "\nOne or more of the required arguments is missing or incorrect." + "\nRun the command with no arguments to see help."); // Create an EC2 client var ec2Client = new AmazonEC2Client(); // Create an object with the necessary properties RunInstancesRequest request = GetRequestData(groupID, ami, keyPairName, subnetID); // Launch the instances and wait for them to start running var instanceIds = await LaunchInstances(ec2Client, request); await CheckState(ec2Client, instanceIds); } // // Method to put together the properties needed to launch the instance. private static RunInstancesRequest GetRequestData( string groupID, string ami, string keyPairName, string subnetID) { // Common properties var groupIDs = new List<string>() { groupID }; var request = new RunInstancesRequest() { // The first three of these would be additional command-line arguments or similar. InstanceType = InstanceType.T1Micro, MinCount = 1, MaxCount = 1, ImageId = ami, KeyName = keyPairName }; // Properties specifically for EC2 in a VPC. if(!string.IsNullOrEmpty(subnetID)) { request.NetworkInterfaces = new List<InstanceNetworkInterfaceSpecification>() { new InstanceNetworkInterfaceSpecification() { DeviceIndex = 0, SubnetId = subnetID, Groups = groupIDs, AssociatePublicIpAddress = true } }; } // Properties specifically for EC2-Classic else { request.SecurityGroupIds = groupIDs; } return request; } // // Method to launch the instances // Returns a list with the launched instance IDs private static async Task<List<string>> LaunchInstances( IAmazonEC2 ec2Client, RunInstancesRequest requestLaunch) { var instanceIds = new List<string>(); RunInstancesResponse responseLaunch = await ec2Client.RunInstancesAsync(requestLaunch); Console.WriteLine("\nNew instances have been created."); foreach (Instance item in responseLaunch.Reservation.Instances) { instanceIds.Add(item.InstanceId); Console.WriteLine($" New instance: {item.InstanceId}"); } return instanceIds; } // // Method to wait until the instances are running (or at least not pending) private static async Task CheckState(IAmazonEC2 ec2Client, List<string> instanceIds) { Console.WriteLine( "\nWaiting for the instances to start." + "\nPress any key to stop waiting. (Response might be slightly delayed.)"); int numberRunning; DescribeInstancesResponse responseDescribe; var requestDescribe = new DescribeInstancesRequest{ InstanceIds = instanceIds}; // Check every couple of seconds int wait = 2000; while(true) { // Get and check the status for each of the instances to see if it's past pending. // Once all instances are past pending, break out. // (For this example, we are assuming that there is only one reservation.) Console.Write("."); numberRunning = 0; responseDescribe = await ec2Client.DescribeInstancesAsync(requestDescribe); foreach(Instance i in responseDescribe.Reservations[0].Instances) { // Check the lower byte of State.Code property // Code == 0 is the pending state if((i.State.Code & 255) > 0) numberRunning++; } if(numberRunning == responseDescribe.Reservations[0].Instances.Count) break; // Wait a bit and try again (unless the user wants to stop waiting) Thread.Sleep(wait); if(Console.KeyAvailable) break; } Console.WriteLine("\nNo more instances are pending."); foreach(Instance i in responseDescribe.Reservations[0].Instances) { Console.WriteLine($"For {i.InstanceId}:"); Console.WriteLine($" VPC ID: {i.VpcId}"); Console.WriteLine($" Instance state: {i.State.Name}"); Console.WriteLine($" Public IP address: {i.PublicIpAddress}"); Console.WriteLine($" Public DNS name: {i.PublicDnsName}"); Console.WriteLine($" Key pair name: {i.KeyName}"); } } // // Command-line help private static void PrintHelp() { Console.WriteLine( "\nUsage: EC2LaunchInstance -g <group-id> -a <ami-id> -k <keypair-name> [-s <subnet-id>]" + "\n -g, --group-id: The ID of the security group." + "\n -a, --ami-id: The ID of an Amazon Machine Image." + "\n -k, --keypair-name - The name of a key pair." + "\n -s, --subnet-id: The ID of a subnet. Required only for EC2 in a VPC."); } } // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // Class that represents a command line on the console or terminal. // (This is the same for all examples. When you have seen it once, you can ignore it.) static class CommandLine { // // Method to parse a command line of the form: "--key value" or "-k value". // // Parameters: // - args: The command-line arguments passed into the application by the system. // // Returns: // A Dictionary with string Keys and Values. // // If a key is found without a matching value, Dictionary.Value is set to the key // (including the dashes). // If a value is found without a matching key, Dictionary.Key is set to "--NoKeyN", // where "N" represents sequential numbers. public static Dictionary<string,string> Parse(string[] args) { var parsedArgs = new Dictionary<string,string>(); int i = 0, n = 0; while(i < args.Length) { // If the first argument in this iteration starts with a dash it's an option. if(args[i].StartsWith("-")) { var key = args[i++]; var value = key; // Check to see if there's a value that goes with this option? if((i < args.Length) && (!args[i].StartsWith("-"))) value = args[i++]; parsedArgs.Add(key, value); } // If the first argument in this iteration doesn't start with a dash, it's a value else { parsedArgs.Add("--NoKey" + n.ToString(), args[i++]); n++; } } return parsedArgs; } // // Method to get an argument from the parsed command-line arguments // // Parameters: // - parsedArgs: The Dictionary object returned from the Parse() method (shown above). // - defaultValue: The default string to return if the specified key isn't in parsedArgs. // - keys: An array of keys to look for in parsedArgs. public static string GetArgument( Dictionary<string,string> parsedArgs, string defaultReturn, params string[] keys) { string retval = null; foreach(var key in keys) if(parsedArgs.TryGetValue(key, out retval)) break; return retval ?? defaultReturn; } // // Method to exit the application with an error. public static void ErrorExit(string msg, int code=1) { Console.WriteLine("\nError"); Console.WriteLine(msg); Environment.Exit(code); } } }
추가 고려 사항
-
EC2 인스턴스의 상태를 확인할 때 DescribeInstancesRequest 객체의
Filter
속성에 필터를 추가할 수 있습니다. 이 기술을 사용하면 요청을 특정 인스턴스(예: 특정 사용자 지정 태그가 있는 인스턴스)로 제한할 수 있습니다.
-
간략하게 나타내기 위해 일부 속성에는 일반적인 값이 지정되었습니다. 대신 프로그래밍 방식으로 또는 사용자 입력을 통해 이러한 속성 중 일부 또는 전체를 결정할 수 있습니다.
-
RunInstancesRequest 객체의
MinCount
및MaxCount
속성에 사용할 수 있는 값은 대상 가용 영역과 인스턴스 유형에 허용되는 최대 인스턴스 수에 따라 결정됩니다. 자세한 내용은 Amazon EC2 General Word의 Amazon Word에서 실행할 수 있는 인스턴스수를 참조하세요FAQ. EC2
-
이 예제와 다른 인스턴스 유형을 사용하려면 선택할 수 있는 여러 인스턴스 유형이 있습니다. 자세한 내용은 Amazon EC2 사용 설명서의 Amazon Word 인스턴스 유형을 참조하세요. EC2 인스턴스 유형 세부 정보
및 인스턴스 유형 탐색 기를 참조하세요.
-
인스턴스를 시작할 때 인스턴스에 IAM 역할을 연결할 수도 있습니다. 이렇게 하려면
Name
속성이 IamInstanceProfileSpecification 역할 이름으로 설정된 IAM 객체를 생성합니다. 그런 다음 해당 객체를 RunInstancesRequest 객체의IamInstanceProfile
속성에 추가합니다.참고
EC2 역할이 연결된 IAM 인스턴스를 시작하려면 IAM 사용자의 구성에 특정 권한이 포함되어야 합니다. 필요한 권한에 대한 자세한 내용은 Amazon IAM 사용 설명서의 인스턴스에 Word 역할을 전달할 수 있는 사용자 권한 부여를 참조하세요. EC2
(선택 사항) 인스턴스에 연결
인스턴스가 실행된 후에는 적절한 원격 클라이언트를 사용하여 인스턴스에 원격으로 연결할 수 있습니다. Linux 인스턴스와 Windows 인스턴스 모두 인스턴스의 퍼블릭 IP 주소 또는 퍼블릭 DNS 이름이 필요합니다. 또한 다음 항목이 필요합니다.
Linux 인스턴스의 경우
SSH 클라이언트를 사용하여 Linux 인스턴스에 연결할 수 있습니다. 에 설명된 대로 인스턴스를 시작할 때 사용한 보안 그룹이 포트 22에서 SSH 트래픽을 허용하는지 확인합니다보안 그룹 업데이트.
인스턴스를 시작하는 데 사용한 키 페어의 프라이빗 부분, 즉 PEM 파일도 필요합니다.
자세한 내용은 Amazon EC2 사용 설명서의 Linux 인스턴스에 연결을 참조하세요.
Windows 인스턴스의 경우
RDP 클라이언트를 사용하여 인스턴스에 연결할 수 있습니다. 에 설명된 대로 인스턴스를 시작할 때 사용한 보안 그룹이 포트 3389에서 RDP 트래픽을 허용하는지 확인합니다보안 그룹 업데이트.
또한 관리자 암호가 필요합니다. 인스턴스 ID와 인스턴스를 시작하는 데 사용되는 키 페어의 프라이빗 부분, 즉 PEM 파일이 필요한 다음 예제 코드를 사용하여 이를 얻을 수 있습니다.
자세한 내용은 Amazon EC2 사용 설명서의 Windows 인스턴스에 연결을 참조하세요.
주의
이 예제 코드는 인스턴스의 일반 텍스트 관리자 암호를 반환합니다.
NuGet 패키지:
프로그래밍 요소:
-
네임스페이스 Amazon.EC2
클래스 AmazonEC2Client
-
네임스페이스 Amazon.EC2.모델
using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Amazon.EC2; using Amazon.EC2.Model; namespace EC2GetWindowsPassword { // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // Class to get the Administrator password of a Windows EC2 instance class Program { static async Task Main(string[] args) { // Parse the command line and show help if necessary var parsedArgs = CommandLine.Parse(args); if(parsedArgs.Count == 0) { PrintHelp(); return; } // Get the application arguments from the parsed list string instanceID = CommandLine.GetArgument(parsedArgs, null, "-i", "--instance-id"); string pemFileName = CommandLine.GetArgument(parsedArgs, null, "-p", "--pem-filename"); if( (string.IsNullOrEmpty(instanceID) || !instanceID.StartsWith("i-")) || (string.IsNullOrEmpty(pemFileName) || !pemFileName.EndsWith(".pem"))) CommandLine.ErrorExit( "\nOne or more of the required arguments is missing or incorrect." + "\nRun the command with no arguments to see help."); // Create the EC2 client var ec2Client = new AmazonEC2Client(); // Get and display the password string password = await GetPassword(ec2Client, instanceID, pemFileName); Console.WriteLine($"\nPassword: {password}"); } // // Method to get the administrator password of a Windows EC2 instance private static async Task<string> GetPassword( IAmazonEC2 ec2Client, string instanceID, string pemFilename) { string password = string.Empty; GetPasswordDataResponse response = await ec2Client.GetPasswordDataAsync(new GetPasswordDataRequest{ InstanceId = instanceID}); if(response.PasswordData != null) { password = response.GetDecryptedPassword(File.ReadAllText(pemFilename)); } else { Console.WriteLine($"\nThe password is not available for instance {instanceID}."); Console.WriteLine($"If this is a Windows instance, the password might not be ready."); } return password; } // // Command-line help private static void PrintHelp() { Console.WriteLine( "\nUsage: EC2GetWindowsPassword -i <instance-id> -p pem-filename" + "\n -i, --instance-id: The name of the EC2 instance." + "\n -p, --pem-filename: The name of the PEM file with the private key."); } } // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // Class that represents a command line on the console or terminal. // (This is the same for all examples. When you have seen it once, you can ignore it.) static class CommandLine { // // Method to parse a command line of the form: "--key value" or "-k value". // // Parameters: // - args: The command-line arguments passed into the application by the system. // // Returns: // A Dictionary with string Keys and Values. // // If a key is found without a matching value, Dictionary.Value is set to the key // (including the dashes). // If a value is found without a matching key, Dictionary.Key is set to "--NoKeyN", // where "N" represents sequential numbers. public static Dictionary<string,string> Parse(string[] args) { var parsedArgs = new Dictionary<string,string>(); int i = 0, n = 0; while(i < args.Length) { // If the first argument in this iteration starts with a dash it's an option. if(args[i].StartsWith("-")) { var key = args[i++]; var value = key; // Check to see if there's a value that goes with this option? if((i < args.Length) && (!args[i].StartsWith("-"))) value = args[i++]; parsedArgs.Add(key, value); } // If the first argument in this iteration doesn't start with a dash, it's a value else { parsedArgs.Add("--NoKey" + n.ToString(), args[i++]); n++; } } return parsedArgs; } // // Method to get an argument from the parsed command-line arguments // // Parameters: // - parsedArgs: The Dictionary object returned from the Parse() method (shown above). // - defaultValue: The default string to return if the specified key isn't in parsedArgs. // - keys: An array of keys to look for in parsedArgs. public static string GetArgument( Dictionary<string,string> parsedArgs, string defaultReturn, params string[] keys) { string retval = null; foreach(var key in keys) if(parsedArgs.TryGetValue(key, out retval)) break; return retval ?? defaultReturn; } // // Method to exit the application with an error. public static void ErrorExit(string msg, int code=1) { Console.WriteLine("\nError"); Console.WriteLine(msg); Environment.Exit(code); } } }
정리
EC2 인스턴스가 더 이상 필요하지 않은 경우에 설명된 대로 종료해야 합니다Amazon EC2 인스턴스 종료.