Configuration for running yum on instance in private subnet
We will check how to run yum on an instance in a private subnet.
Environment

We will check yum execution from an instance in a private subnet with the following two patterns.
- access the yum repository on the Internet via the NAT gateway and execute yum *pattern 1
- access the yum repository on the S3 bucket via the VPC endpoint and execute yum *pattern 2
CloudFormation template files
We will build the above configuration using CloudFormation.
The CloudFormation template is placed at the following URL
Template file points
We will cover the key points of each template file to configure this environment.
Deploy NAT gateways on public subnets
First, we will check the resources around the public subnet.
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCidrBlock
EnableDnsHostnames: true
EnableDnsSupport: true
IGW:
Type: AWS::EC2::InternetGateway
IGWAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref IGW
EIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
NATGateway:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt EIP.AllocationId
SubnetId: !Ref PublicSubnet
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref CidrIp1
VpcId: !Ref VPC
AvailabilityZone: !Sub ${AWS::Region}${AvailabilityZone1}
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
RouteToInternet:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref IGW
Code language: YAML (yaml)
Define Internet Gateways and Public Subnets.
A public subnet is a subnet with a direct Internet gateway facing route. This time, we will create a route table for the public subnet and define the default route for the Internet gateway. The default route can be created by specifying “0.0.0.0/0” for the DestinationCidrBlock property.
Place the NAT gateway in the public subnet.
A NAT gateway is a Network Address Translation (NAT) service. You can use a NAT gateway so that instances in a private subnet can connect to services outside your VPC but external services cannot initiate a connection with those instances.
NAT gateways
By deploying NAT gateways, instances 1 in the private subnet described below will be able to perform outbound communication for the Internet.
Configure NAT gateway-oriented routes in route table
Check the resources around the private subnet 1.
Resources:
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref CidrIp2
VpcId: !Ref VPC
AvailabilityZone: !Sub ${AWS::Region}${AvailabilityZone1}
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
RouteToNATGateway:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway
PrivateSubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet1
RouteTableId: !Ref PrivateRouteTable1
Code language: YAML (yaml)
The instances in the private subnet 1 will run yum through the NAT gateway. Therefore, prepare a route table for this subnet and define the default route for the NAT gateway.
Prepare route table for VPC endpoints
Check the resources around the private subnet 2.
Resources:
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
PrivateSubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref PrivateRouteTable2
Code language: YAML (yaml)
The instances in the private subnet 2 will run yum via the S3 endpoint. Therefore, we need to prepare a route table for this subnet.
The specific route definition will be specified when defining the endpoint.
Allow S3 endpoint to access yum repository for Amazon Linux
Check the resources related to the S3 endpoint.
Resources:
S3Endpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal: '*'
Action:
- s3:GetObject
Resource:
- !Sub arn:aws:s3:::amazonlinux.${AWS::Region}.amazonaws.com/*
- !Sub arn:aws:s3:::amazonlinux-2-repos-${AWS::Region}/*
RouteTableIds:
- !Ref PrivateRouteTable2
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
VpcId: !Ref VPC
Code language: YAML (yaml)
Normally, in order to run yum, you need to access a yum repository on the Internet. However, as an exception, if the OS of your EC2 instance is Amazon Linux (2), you can access the yum repository for that OS without going through the Internet by setting up a VPC endpoint for S3.
Amazon Linux repositories are hosted in Amazon Simple Storage Service (Amazon S3) buckets. To update and install packages on your instance without an internet connection, create an S3 Amazon Virtual Private Cloud (Amazon VPC) gateway endpoint. In the S3 VPC gateway endpoint, include a policy that allows access to the repositories buckets. Then, associate the VPC endpoint with the routing table of your instance subnet.
How can I update yum or install packages without internet access on my EC2 instances running Amazon Linux 1 or Amazon Linux 2?
In this configuration, we will create an EC2 instance of Amazon Linux 2. The policies required for this instance to access the repository on S3 are mentioned below.
The S3 buckets arn:aws:s3:::amazonlinux.region.amazonaws.com and arn:aws:s3:::amazonlinux-2-repos-region/* host the repositories. The following is an example policy allowing the s3:GetObject API call. Replace region with your AWS Region.
How can I update yum or install packages without internet access on my EC2 instances running Amazon Linux 1 or Amazon Linux 2?
Set the Action and Resource properties of the VPC endpoint as described above, and specify the route table for the private subnet (2) in the RouteTableIds property as described above.
Instances in private subnets do not need public address
Check the EC2-related resources.
Resources:
Instance1:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref PrivateSubnet1
GroupSet:
- !Ref InstanceSecurityGroup
Instance2:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref PrivateSubnet2
GroupSet:
- !Ref InstanceSecurityGroup
Code language: YAML (yaml)
No special configuration is required.
Place two instances, one on each of the two private subnets.
The point is that there is no need to set a public address.
When instance 1 communicates, it does not need a public address because it uses the Elastic IP address given to the NAT gateway when exiting to the Internet.
Instance 2 does not need a public address because it does not go through the Internet in the first place.
Accessing EC2 instance via SSM Session Manager
The most common way to access EC2 instances is via SSH using a key pair, but it is also possible to access them using SSM Session Manager.
To access an EC2 instance using this service, you need to set up an endpoints for the service, create a security group for the endpoint, create an IAM role that includes permissions to access the service, and attach it to the instance.
Please refer to the following page for details.
Architecting
Using CloudFormation, we will build this environment and check its actual behavior.
Create CloudFormation stack and check resources in stacks
Create a CloudFormation stack.
For instructions on how to run CloudFormation from the AWS CLI, please refer to the following page.
After checking the resources for each stack, the following information is available for the main resources created this time.
- ID of Instance 1: i-02c9af257d624677e
- ID of instance 2: i-0635909198866aa1b
- ID of PrivateSubet1: subnet-091d74d3795b13935
- ID of PrivateSubet2: subnet-0a3135f67e2a4dffd
- ID of NAT gateway: nat-06dc9f13d6fbb74b7
- ID of VPC endpoint for S3: vpce-0ad8a5eb1d7adcfbe
We will also check the resource creation status in the AWS Managemet Console.
First, we will check the route table for pattern 1.

The default route for the NAT gateway is defined, and you can access the yum repository on the Internet through the NAT gateway.
Next, we will check the route table for pattern 2.

A route to the VPC endpoint for S3 has been defined. A prefix list is set for the destination of this route. The contents of the list are as follows

The CIDR is entered for 10 lines. In other words, by defining one route for the VPC endpoint for S3, if the destination is the above, it will be routed to the same endpoint.
Operation check 1: yum via NAT gateway
Now that we are ready, let’s check the actual behavior.
First, let’s check the yum via NAT gateway.
Access instance 1 via SSM Session Manager.
$ aws ssm start-session \
--target i-02c9af257d624677e
Starting session with SessionId: root-0d0faefc86ccd5a14
sh-4.2$
Code language: Bash (bash)
Check if you can access the Internet by pinging it.
sh-4.2$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=104 time=2.88 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=104 time=2.43 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=104 time=2.47 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=104 time=2.48 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 2.432/2.568/2.888/0.185 ms
Code language: Bash (bash)
Sure enough, you can access the Internet through the NAT gateway.
Now run yum.
sh-4.2$ sudo yum install httpd -y
...
Installed:
httpd.x86_64 0:2.4.48-2.amzn2
...
Complete!
Code language: Bash (bash)
I was able to run it successfully.
We found that we could access the yum repository on the Internet through the NAT gateway and run yum.
Operation check 2: yum via VPC endpoint
Next, we will check yum via S3 endpoint.
Access instance 2 via SSM Session Manager.
$ aws ssm start-session \
--target i-0635909198866aa1b
Starting session with SessionId: root-01e1d55c4aaf53e13
sh-4.2
Code language: Bash (bash)
Check if you can access the Internet by pinging it.
sh-4.2$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
28 packets transmitted, 0 received, 100% packet loss, time 27624ms
Code language: Bash (bash)
It’s still not possible. This is because there is no route to the Internet in private subnet 2.
Now run yum.
sh-4.2$ sudo yum install httpd -y
...
Installed:
httpd.x86_64 0:2.4.48-2.amzn2
...
Complete!
Code language: Bash (bash)
We were able to run it successfully.
We found that we can access the yum repository on the S3 bucket via the VPC endpoint and run yum.
Summary
We have identified two patterns of how to run yum on an EC2 instance on a private subnet.
The first method is to access the yum repository on the Internet via a NAT gateway and run yum.
The second method is to access the yum repository on the S3 bucket via the VPC endpoint and run yum.