# VPC Endpoints

Today, we will be learning about VPC Endpoints.

### VPC Endpoints

VPC endpoints are **a way to privately connect your VPC to supported AWS services and VPC endpoint services** without requiring an internet gateway, NAT device, VPN, or Direct Connect connection. They allow you to connect to these services using private IP addresses, which keeps your traffic within the AWS network.

There are two types of VPC endpoints:

1. **Interface Endpoints**: These are powered by AWS PrivateLink and are used for connecting to services like S3, DynamoDB. They provide a private IP address in your VPC. When you create an interface endpoint, an Elastic Network Interface (ENI) is created in your subnet with a private IP address that serves as the entry point for traffic destined to the service.
    
2. **Gateway Endpoints**: These are used for connecting to S3 and DynamoDB and are simpler to set up than interface endpoints. Gateway endpoints are associated with your route table and use route tables to direct traffic to the endpoint.
    

---

### Overview

We will set up a VPC with two subnets: one public and one private. Each subnet will have one instance. We will attach a role to the private instance to allow it to list the available S3 buckets. This will be done utilizing the Gateway Endpoint which establishes a private connection within our VPC to access S3, eliminating the need for an internet gateway.

---

### Task 1: Creating a VPC

Search for **VPC** in the search box.

Click on `Create VPC`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718275236554/381ff049-59bd-4f76-9c9a-a161a8ff1eba.png align="left")

Provide a name for your VPC and input a CIDR range.

Click on `Create VPC`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718358456677/9090fb5b-fac5-41ab-8705-1950134aedee.png align="center")

---

### Task 2: Creating an Internet Gateway

On **Internet gateways**, click on `Create internet gateway`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718289173594/d0716e80-3fd1-46f8-a588-382d2b770063.png align="left")

Provide a suitable name and click on `Create internet gateway`.

After creating an Internet gateway, attach it to your VPC.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718358529060/2570159d-4a75-4807-af8d-4da48addb0ac.png align="center")

---

### Task 3: Creating Subnets

On **Subnets**, click on `Create subnet`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718275316282/ed97305e-b8bf-405b-aae0-320c42400d32.png align="center")

We are going to create two subnets: one public and one private.

Select your VPC.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718286107613/c698c3f8-61d7-4c74-bffc-03956725a15d.png align="left")

Provide a suitable name for your subnet, choose an AZ and input an eligible CIDR range value.

Click on `Add new subnet`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718286192712/181df224-a862-4464-980b-b4f5dd34a3d7.png align="left")

Provide a suitable name and CIDR range.

Click on `Create subnet`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718358687132/8923bdfc-bddf-4416-b417-a0249b7fc553.png align="center")

---

### Task 4: Creating Route table

On **Route tables**, click on `Create route table`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718275513777/9105256f-bef2-4322-9ec1-764d0a95338f.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718286258718/863a0a91-5154-48b8-8ded-32b8d974b78b.png align="left")

Provide a suitable name for your route table, select your VPC and click on `Create route table`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718286341371/2856efe7-8e98-4940-ba4b-e88507d3482d.png align="left")

On **Subnet associations**, click on `Edit subnet associations`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718286379779/a442ebdc-b93a-4fb6-b630-dbc004200302.png align="center")

Tick your public subnet and click on `Save associations`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718289867853/36d1b6a6-ddb8-4915-aabb-89634c81855d.png align="left")

Now on **Routes**, click on `Edit routes`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718289898816/1666c56d-316c-42c0-98b9-ec92769785ce.png align="center")

Configure a route to Internet gateway and click on `Save changes`.

Now it's time to create another route table & associate private subnet.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718286429558/8290a738-7419-428d-9af1-cd1b3ec9f69d.png align="left")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718286453378/3f3760c7-0236-4ca7-b2e3-a9e5e129aaa6.png align="center")

We should not include an Internet Gateway route in the private route table.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718286533113/1cd2b2af-6ec3-4464-a26e-a9f68115489f.png align="center")

We have created two route tables.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718358861054/590a0e19-7c1f-4426-96c2-9e427d3aadc9.png align="center")

---

### Task 5: Creating a Role

Search for `IAM` in the search box.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718278111705/8e6e0393-d77d-427a-b026-986202182dd5.png align="left")

On **Roles**, click on `Create role`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718278151242/3ef55e03-5cc6-4e27-844d-4f4164346743.png align="left")

Select **AWS Service** as the trusted entity type and **EC2** for the use case.

By choosing AWS Service as the trusted entity type, we specify that this role is intended for use by an AWS service, in this case, EC2. This allows EC2 instances to assume this role and inherit the permissions defined in the role's policy.

Click on `Next`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718278482411/d6d06e64-75f0-4845-89b2-9831369cf003.png align="left")

We are attaching S3 read only permission to our instance.

Click on **'+'** sign to expand the policy.

Click on `Next`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718278566812/aa2a9d2e-9c78-4ab9-ae2c-ceda800d1518.png align="left")

Provide a suitable name for your role and review your created role.

Click on `Create role`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718278652799/fc5f37d4-ca1f-4e7c-ba5e-3d2e6184dfd4.png align="center")

We have created a role.

---

### Task 6: Creating EC2 instance.

Search for **EC2** in the search box.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718278732264/f15264f6-f534-47ed-9d09-59ccc6355cbc.png align="left")

On **Instances**, click on `Launch instances`.

Provide a name for your instance, select an Amazon Linux AMI (**mandatory**) and a free-tier instance if possible. Either use existing or create a new key pair.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718293117409/13579491-69cc-40cd-90ab-0c6c13a15395.png align="left")

Edit Network settings. Select your VPC and your subnet.

Leaving all other configurations as default, click on `Launch instance`.

Now, let's create a private instance.

Provide a name for your instance, select an Amazon Linux AMI and a free-tier instance if possible. Either use existing or create a new key pair.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718293230293/4adc91b1-8d73-4cad-98ad-a5446e3b1556.png align="left")

Select your VPC, choose private subnet and keep other as default.

Leaving all other configurations as default, scroll to the bottom **Advanced Details**.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718279086946/22f7743a-8979-48d2-9577-87a69a7a634c.png align="left")

On **IAM instance profile**, select your created role.

Now, keeping all other settings as default, click on `Launch instance`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718293301560/7f2378fa-9d91-4b3c-9466-0984b1b49b04.png align="center")

We have created two EC2 instances.

diagram..

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718359055537/1540dc65-de56-45a3-ac93-f38d77673d1f.png align="center")

---

### Task 7: Creating s3 buckets.

Search for **s3** in the search box.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718279529504/35c8b250-730c-49d6-9ff6-3efd1993e2dd.png align="left")

On **Buckets**, click on `Create bucket`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718279642904/e6d41eca-02fd-420b-b769-ccd1cd055229.png align="left")

Just provide a name for your bucket and leaving all other configurations as it is, click on `Create bucket`.

Let's create another bucket as well.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718279730961/bf28965b-8762-4e35-affb-d8319996bc34.png align="left")

So, we have created two buckets.

---

### Task 8: Accessing EC2s

We need to copy the private key required to SSH into the private server from our public server first.

Open your local terminal.

Modify the code below to suit your needs.

```bash
scp -i "publicServerKey.pem" "privateServerKey.pem" ec2-user@13.233.225.53:/home/ec2-user
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718293674304/a48822e7-da2f-4702-8991-b258a4deebf1.png align="center")

This command copies the file `privateServerKey.pem` from our local machine to the `/home/ec2-user` directory on the remote server with IP address `13.233.225.53` using the SSH key specified by `publicServerKey.pem`.

Now, let's SSH into our public instance.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718293771481/11f3e83c-798e-4a29-b9d4-fd6483b4492a.png align="left")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718293830355/0ef5a992-1b0b-44f8-b9bb-e97b5b791994.png align="left")

We have securely copied the key to our public instance, which will be used to SSH into our private instance.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718293891290/f2a2ce52-9e7c-4571-a674-474a0e78b767.png align="left")

Copy & paste the command in your public instance's terminal.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718293913040/1dc3498c-2603-47cb-b4b4-74e255607be0.png align="left")

Now, copy the SSH command to establish a connection to the private instance.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718293995426/c0eab9a8-5e05-4348-b5de-de05bfad0bcb.png align="center")

Proceed with yes.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718294031609/3e6b64d5-5d6c-4487-80d0-d43bbaa9e100.png align="center")

We are now connected to our private instance.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718294082161/b389e18d-837b-4d3a-b269-32e2538b84b1.png align="left")

Even though we have attached the role that allows an EC2 instance to list S3 buckets, we are unable to do so due to a lack of connection. This is where we set up a VPC endpoint.

---

### Task 9: Creating a VPC endpoint.

Go to the **VPC dashboard**.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718294235172/f012327e-55e4-457e-b8bb-4245eb55f848.png align="left")

On **Endpoints**, click on `Create endpoint`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718294302505/ee8c2a4a-cb68-46cf-a5ea-7c82f570a46a.png align="left")

Provide a name for your endpoint.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718294689173/c1f54ae7-c6a1-47a8-8099-603b1e64aeee.png align="left")

In the services, look for **S3** and select it. This VPC endpoint will be used to access S3, indicating that the services it will be consuming or using are related to S3.

Choose the service name `com.amazonaws.<your-region>.s3` to create the VPC endpoint for standard Amazon S3 in the `<your-region>`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718294756390/3f8a9f71-8ffb-4712-b4a4-0c32fda55981.png align="left")

Select the Gateway type & select your VPC.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718294994801/6b6058c9-0573-47ef-96aa-e46de1c382af.png align="left")

Select only your private route table, as we're allowing EC2 instance in the private subnet to perform actions on S3 buckets using the endpoint.

Click on `Create endpoint`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718295192440/d9c5abeb-b29e-434e-ad1c-60ff9d65bed8.png align="center")

Now that we've created our VPC Endpoint, let's return to our EC2 terminal and run the same command to see if it's working.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718295266175/957ca9c6-3472-4237-98fc-dfece16d952f.png align="left")

We can now list the S3 buckets, demonstrating that a private instance within our VPC can securely communicate with other AWS services.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718361792287/df1f9afa-9964-4265-a21b-77834e1a0b1b.png align="center")

---

### Conclusion

By attaching a role to the private instance and utilizing the Gateway Endpoint, we have enabled it to perform operations on S3 buckets securely. This setup establishes a private connection from our VPC to S3, allowing communication to occur without the need for an internet gateway.

---

### Task 10: Clean Up

1. **Terminating EC2 instances**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718295557381/d2d812bb-e0f1-4765-9751-e7b87b8cf5b7.png align="center")
    
    Select both of your instances and on **Instance state,** click on `Terminate instance`.
    
2. **Deleting VPC Endpoint**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718295622016/f541b289-5288-407e-8696-ea801173e529.png align="left")
    
    Select your Endpoint and in the **Actions** panel, click on `Delete VPC endpoints`.
    
3. **Deleting subnets.**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718295735883/5cc94a7e-8446-4e72-b48c-880ff58572ad.png align="left")
    
    Select both of your subnets and in the **Actions** panel, click on `Delete subnet`. Refresh the page if you are not able to delete.
    
4. **Deleting VPC.**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718295813365/51dcb3a5-846a-4422-8460-d519906b3fa3.png align="left")
    
    Select your VPC and in the **Actions** panel, click on `Delete VPC`.
    
5. **Deleting s3 buckets.**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718295892686/c12ed6e0-db7e-409b-9b29-80dd09478a79.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1718295933358/676fa7a9-5c42-4e11-919e-84ab0ca789b0.png align="center")
    
    Select your bucket and click on `Delete` button.
    

We have cleaned up our used resources.

---

That was it for today.

I'll see you in the next one!
