- An AWS account
- Basic understanding of Amazon EC2
- Understanding of programming using C# .NET Core
- Keys to access AWS resources outside the console (If you don’t have them, don’t worry. I’ll show you how to get them later in the tutorial)
Road Map
- Creating an ASP.NET Core Web API Project
- Installing required packages
- Setting up the Controller Class
- Creating Services
- Implementing methods
- Getting the AWS Access/Secret keys (optional)
- Test using Postman
- Use Cases
Creating a Web API Project
Step 1
Open Visual Studio, select Create a New project and select
ASP.NET Core Web Application.
Step 2
Provide a meaningful name and select Create.
Step 3
Select API in the next screen and click on Create.
Installing Required Packages
Step 1
We will be needing two NuGet packages, the first one is AWSSDK.Extensions.NETCore.Setup.
Step 2
Install the second one. The second one is AWSSDK.EC2.
Step 3
Add the following lines of code in the ConfigureServices() method of Startup.cs.
- public void ConfigureServices(IServiceCollection services) {
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
- services.AddSingleton < IEC2Service, EC2Service > ();
- services.AddAWSService < IAmazonEC2 > ();
- }
Setting up the Controller class
Step 1
First rename the Controller as EC2InstanceController, remove the auto generated code and the following code (Don’t worry about the errors, we will create IEC2Service interface in a bit).
- [Produces("application/json")]
- [Route("api/EC2Instance")]
- [ApiController]
- public class ValuesController: ControllerBase {
- private readonly IEC2Service _service;
-
- public EC2InstanceController(IEC2Service service) {
- _service = service;
- }
- [HttpPost("{amiID}")]
- public async Task < IActionResult > CreateEC2Instance([FromRoute] string amiID) {
- var response = await _service.CreateInstanceAsync(amiID);
- return Ok(response);
- }
- [HttpDelete("{instanceId}")]
- public async Task < IActionResult > DeleteEC2Instance([FromRoute] string instanceId) {
- var response = await _service.TerminateInstanceAsync(instanceId);
- return Ok(response);
- }
- }
Step 2
Go to launchSettings.json file and delete the following line.
Creating Services and Implementing methods
Step 1
Create a folder named Services in the project.
Step 2
Create an interface IEC2Service in this folder and add the following code.
- public interface IEC2Service {
- Task < EC2Response > CreateInstanceAsync(string amiID);
- Task < EC2Response > TerminateInstanceAsync(string instanceId);
- }
Step 3
Create a class EC2Service which will implement this interface, and add the following code.
- private readonly IAmazonEC2 _client;
- public EC2Service(IAmazonEC2 client) {
- _client = client;
-
- }
To remove the error for IAmazonEC2, add the reference of the SDK that we installed earlier.
Step 4
Create a new folder Models, and add a new class EC2response. This class will be used to send response back from the API. Add the following code in that class.
- public class EC2Response {
- public HttpStatusCode Status {
- get;
- set;
- }
- public string Message {
- get;
- set;
- }
- }
Step 5
Let’s implement the first method CreateInstanceAsync().
- First we will have to create a security group for that instance, write the following code.
- var createRequest = new CreateSecurityGroupRequest {
- GroupName = "testSecGroup",
- Description = "My sample security group for EC2-Classic"
- };
-
- var createResponse = await _client.CreateSecurityGroupAsync(createRequest);
-
- var Groups = new List < string > () {
- createResponse.GroupId
- };
- var describeRequest = new DescribeSecurityGroupsRequest() {
- GroupIds = Groups
- };
- var describeResponse = await _client.DescribeSecurityGroupsAsync(describeRequest);
We will use the GroupId of this group later.
-
Create an IP Range permission in order to connect to this instance using SSH, use the following code.
- IpRange ipRange = new IpRange {
- CidrIp = "1.1.1.1/1"
- };
- List < IpRange > ranges = new List < IpRange > {
- ipRange
- };
-
- var ipPermission = new IpPermission {
- IpProtocol = "tcp",
- FromPort = 22,
- ToPort = 22,
- Ipv4Ranges = ranges
- };
-
- var ingressRequest = new AuthorizeSecurityGroupIngressRequest {
- GroupId = describeResponse.SecurityGroups[0].GroupId
- };
- ingressRequest.IpPermissions.Add(ipPermission);
- var ingressResponse = await _client.AuthorizeSecurityGroupIngressAsync(ingressRequest);
CidrIp = 1.1.1.1/1 means that it will allow any ip address to connect to the instance from Putty.
-
Create a Key Pair that will be used to connect to the instance with Putty and save in a .pem file. Use the following code.
- var request = new CreateKeyPairRequest {
- KeyName = "testKeyPair"
- };
-
- var response = await _client.CreateKeyPairAsync(request);
- Console.WriteLine();
- Console.WriteLine("New key: " + "testKeyPair");
-
-
- using(FileStream s = new FileStream("privatekeyFike.pem", FileMode.Create))
- using(StreamWriter writer = new StreamWriter(s)) {
- writer.WriteLine(response.KeyPair.KeyMaterial);
- }
-
Now create a launch request and try to run the instance. The AMI ID will be passed from the request, you can use any AMI to launch an instance. Provide the Min, Max count, Instance type, KeyPair and Securitygroup configuration. Use the following code.
- string keyPairName = "testKeyPair";
-
- List < string > groups = new List < string > () {
- describeResponse.SecurityGroups[0].GroupId
- };
- var launchRequest = new RunInstancesRequest() {
- ImageId = amiID,
- InstanceType = InstanceType.T2Micro,
- MinCount = 1,
- MaxCount = 1,
- KeyName = keyPairName,
- SecurityGroupIds = groups,
- };
-
- var launchResponse = await _client.RunInstancesAsync(launchRequest);
-
- return new EC2Response {
- Message = launchResponse.ResponseMetadata.RequestId,
- Status = launchResponse.HttpStatusCode
- };
Now you are able to create and launch an EC2 instance based on any AMI.
Step 6
Let’s implement the second method, TerminateInstanceAsync(string instanceId), which will take instanceId as an input and terminate that instance. Keep in mind that stop and terminate are two different things, you won’t be able to start that instance again if you terminate it.
Use the following code.
- public async Task < EC2Response > TerminateInstanceAsync(string instanceId) {
- var request = new TerminateInstancesRequest {
- InstanceIds = new List < string > () {
- instanceId
- }
- };
-
- var response = await _client.TerminateInstancesAsync(request);
- foreach(InstanceStateChange item in response.TerminatingInstances) {
- return new EC2Response {
- Message = "Terminated instance: " + item.InstanceId + "--State:" + item.CurrentState.Name,
- Status = response.HttpStatusCode,
-
- };
-
- }
- return new EC2Response {
- Status = HttpStatusCode.InternalServerError,
- Message = "Something Went Wrong"
- };
- }
Getting AWS Access/Secret keys (Optional)
This step is optional if you already know how to get the keys, or already have the keys configured in the .aws folder. This would be common for people that use AWS CLI. But keep in mind that you can’t connect to AWS outside the management console if you don’t have access keys and you’ll get exceptions and your code won’t work as desired.
You’ll be prompted to enter your keys and your default region, e.g.
- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- us-west-2
Now you’re good to go. Now you can access the resources outside the management console of AWS.
Testing using Postman
Now when you have successfully created an API that will launch and terminate an EC2 instance on a REST request, let’s test it using postman.
- First test the Create Instance (POST) request as follows.
See we have a status code of OK which means our instance has been created successfully. Let’s check this out on management console.
- Go to the management console and see the result.
We can see that the instance is created and it is now running.
-
Let’s copy its Instance ID and try to terminate it using the HTTP DELETE request.
We have an OK response which means our instance is terminated successfully.
- Let’s check this on the management console.
Use Cases:
- Developing any application that needs EC2 instance to be created programmatically
- Getting to know how to use the AWS SDK for .NET, .NET Core
- Building applications where you need to create security groups or key pairs for other instances using code.
Summary
In this article, we learned about how to Create, Launch, and terminate an EC2 instance using AWS SDK for .NET.