Amazon EC2 インスタンスの起動 - AWS SDK for .NET

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Amazon EC2 インスタンスの起動

この例では、 を使用して AWS SDK for .NET 、同じ Amazon マシンイメージ (AMI) から 1 つ以上の同一に設定されている Amazon EC2 インスタンスを起動する方法を示します。アプリケーションは指定された複数の入力を使用して EC2 インスタンスを起動し、インスタンスが「Pending」状態でなくなるまでインスタンスを監視します。

EC2 インスタンスが実行中の場合、「(オプション) インスタンスへの接続」の説明に従ってインスタンスにリモートで接続できます。

EC2 インスタンスは、VPC または EC2-Classic で起動できます ( AWS アカウントでサポートされている場合)。詳細については、「Linux インスタンス用 Amazon EC2 ユーザーガイド」または「Windows インスタンス用 Amazon EC2 ユーザーガイド」の「VPC の EC2 とEC2-Classic」を参照してください。

警告

2022 年 8 月 15 日に、EC2-Classic の提供を終了しhます。EC2-Classic は、VPC への移行をお勧めします。詳細については、Linux インスタンス用 Amazon EC2 ユーザーガイドまたはWindows インスタンス用 Amazon EC2 ユーザーガイドの「EC2-Classic から VPC への移行」を参照してください。ブログ記事「EC2-Classic Networking は販売終了になります — 準備方法はこちら」も参照してください。

以下のセクションでは、この例のスニペットとその他の情報を確認できます。スニペットの下には、この例のコードの全文が示されており、そのままビルドして実行できます。

必要な要素を集める

EC2 インスタンスを起動するには、いくつかの要素が必要です。

  • インスタンスを起動する場所である VPC。Windows インスタンスに RDP 経由で接続する場合、VPC にはインターネットゲートウェイが添付され、そのルートテーブル内にインターネットゲートウェイへのエントリを持つ必要があるのが普通です。詳細については、Amazon VPC ユーザーガイドの「インターネットゲートウェイ」を参照してください。

  • インスタンスを起動する VPC 内の既存サブネットの ID。これを簡単に検索または作成するには、Amazon VPC コンソールにサインインしますがCreateSubnetAsyncおよび DescribeSubnetsAsyncメソッドを使用してプログラムで取得することもできます。

    注記

    AWS アカウントが EC2-Classic をサポートしていて、起動するインスタンスのタイプである場合、このパラメータは必要ありません。しかし、お使いのアカウントで EC2-Classic がサポートされておらず、このパラメータも指定されていない場合、新しいインスタンスはアカウントのデフォルトの VPC で起動します。

  • 新しいインスタンスに接続する場合は、前述のセキュリティグループにポート 22 で SSH トラフィックを許可する (Linux インスタンス) か、またはポート 3389 で RDP トラフィックを許可する (Windows インスタンス) 適切なインバウンドルールが設定されている必要があります。設定の方法については、「セキュリティグループの更新」を参照してください (トピックの最後近くにある「追加の考慮事項」を含む)。

  • 既存の EC2 キーペア名。これは新しいインスタンスへの接続に使用されます。詳細については、「Amazon EC2 のキーペアの使用」を参照してください。

  • 前述の EC2 キーペアのプライベートキーを含む PEM ファイルの名前。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 パッケージ:

プログラミング要素:

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 オブジェクトの プロパティMinCountMaxCountプロパティに使用できる値は、ターゲットのアベイラビリティーゾーンと、インスタンスタイプに使用できるインスタンスの最大数によって決まります。詳細については、「Amazon EC2 よくある質問」の「Amazon EC2 ではいくつのインスタンスを実行できますか?」を参照してください。

(オプション) インスタンスへの接続

インスタンスが実行状態になったら、適切なリモートクライアントを使用してインスタンスにリモート接続できます。Linux インスタンスと Windows インスタンスのいずれの場合も、インスタンスのパブリック IP アドレスまたは公開 DNS 名が必要です。また、以下も必要になります。

Linux インスタンスの場合

SSH クライアントを使用して Linux インスタンスに接続できます。「セキュリティグループの更新」の説明に従って、インスタンスの起動時に使用したセキュリティグループで、ポート 22 での SSH トラフィックが許可されていることを確認します。

また、インスタンスの起動に使用したキーペアのプライベート部分、すなわち PEM ファイルも必要です。

詳細については、Linux インスタンス用 Amazon EC2 ユーザーガイドの「Linux インスタンスへの接続」を参照してください。

Windows インスタンスの場合

RDP クライアントを使用してお使いのインスタンスに接続できます。「セキュリティグループの更新」の説明に従って、インスタンスの起動時に使用したセキュリティグループで、ポート 3389 での RDP トラフィックが許可されていることを確認します。

また、管理者パスワードも必要です。取得するには、以下のコード例を使用します。その際、インスタンス ID とインスタンスの起動に使用されたキーペアのプライベート部分、すなわち PEM ファイルが必要です。

詳細については、Windows インスタンス用 Amazon EC2 ユーザーガイドの「Windows インスタンスに接続する」を参照してください。

警告

このサンプルコードは、インスタンスの管理者パスワードをプレーンテキストで返します。

NuGet パッケージ:

プログラミング要素:

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 インスタンスの終了」の説明に従って必ずインスタンスを終了してください。