(aws-ec2): NatInstanceProviderV2 default user data uses 'route' command which is not available on Amazon Linux 2023
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
`NatInstanceProviderV2` default user data script uses the `route` command to detect the default network interface name. However, the `route` command is part of the `net-tools` package, which is not installed by default on Amazon Linux 2023.
Since `NatInstanceProviderV2` uses Amazon Linux 2023 by default, the NAT instance does not function correctly out of the box.
The problematic code in `DEFAULT_USER_DATA_COMMANDS`:
```typescript
"sudo /sbin/iptables -t nat -A POSTROUTING -o $(route | awk '/^default/{print $NF}') -j MASQUERADE",
```
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Expected Behavior
NAT instance forwards traffic correctly.
### Current Behavior
The `route` command does not exist, causing the user data script to fail. The iptables MASQUERADE rule is not configured, and outbound traffic from private subnets is not NAT-ed.
### Reproduction Steps
```typescript
import * as ec2 from 'aws-cdk-lib/aws-ec2';
const vpc = new ec2.Vpc(this, 'Vpc', {
natGatewayProvider: ec2.NatProvider.instanceV2({
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.NANO),
}),
natGateways: 1,
});
```
After deployment, connections from resources in private subnets (Lambda, EC2, etc.) to the internet will fail.
### Possible Solution
Use `ip route` command instead of `route`. The `ip route` command is part of the `iproute2` package, which is installed by default on AL2023.
```typescript
public static readonly DEFAULT_USER_DATA_COMMANDS = [
'yum install iptables-services -y',
'systemctl enable iptables',
'systemctl start iptables',
'echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/custom-ip-forwarding.conf',
'sysctl -p /etc/sysctl.d/custom-ip-forwarding.conf',
'IFACE=$(ip route show default | awk \\'{print $5}\\')',
'/sbin/iptables -t nat -A POSTROUTING -o $IFACE -j MASQUERADE',
'/sbin/iptables -F FORWARD',
'service iptables save',
];
```
### Additional Information/Context
- PR #29729 fixed the hardcoded `eth0` issue by using the `route` command to dynamically detect the interface name
- However, the same PR set `AMAZON_LINUX_2023` as the default `machineImage`, and AL2023 does not have `net-tools` (which contains the `route` command) installed by default
**Workaround**: Pass a custom script via the `userData` property:
```typescript
const natUserData = UserData.forLinux();
natUserData.addCommands(
'yum install iptables-services -y',
'systemctl enable iptables',
'systemctl start iptables',
'echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/custom-ip-forwarding.conf',
'sysctl -p /etc/sysctl.d/custom-ip-forwarding.conf',
"IFACE=$(ip route show default | awk '{print $5}')",
'/sbin/iptables -t nat -A POSTROUTING -o $IFACE -j MASQUERADE',
'/sbin/iptables -F FORWARD',
'service iptables save',
);
const vpc = new ec2.Vpc(this, 'Vpc', {
natGatewayProvider: ec2.NatProvider.instanceV2({
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.NANO),
userData: natUserData,
}),
natGateways: 1,
});
```
### AWS CDK Library version (aws-cdk-lib)
2.178.0
### AWS CDK CLI version
2.178.0
### Node.js Version
v20.x
### OS
macOS
### Language
TypeScript
### Other information
Related Issue/PR:
- #29720 - Original `eth0` hardcoding issue
- #29729 - Fix PR (introduced this issue)
Contributor guide
Research direction
Start at NatInstanceProviderV2 and its DEFAULT_USER_DATA_COMMANDS, focusing on the command that derives the default network interface. Check the related changes in PR #29729 and the reproduction configuration, then verify that the generated user data uses an AL2023-available command and that private-subnet outbound traffic is NATed successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100