1. 개요
NAT Gateway 정보를 확인하고 싶어서 describe-nat-gateways를 사용했다. 나는 Private IP와 NAT Gateway ID 순서로 결과를 출력하고 싶은데, 계속 의도와 다른 순서나 형태로 나온다.
https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/controlling-output.html 문서를 아무리 봐도 큰 도움이 되지 않았다.
2. 테스트
2-1. Case 1
$ aws ec2 describe-nat-gateways --query 'NatGateways[].[NatGatewayAddresses[].PrivateIp,NatGatewayId]' --output text | sed '$!N;s/\n/ /'
결과: 실패
NatGatewayAddresses[].PrivateIp처럼 []를 사용하면 주소 목록을 다시 펼치는 형태가 된다. 이 값은 단일 문자열이 아니라 리스트로 취급될 수 있어서, --output text 결과가 기대한 한 줄짜리 컬럼 형태로 떨어지지 않는다. 이후 sed로 줄을 합치면 겉보기에는 비슷해 보일 수 있지만, 원래 출력 구조가 원하는 형태가 아니기 때문에 안정적인 방법은 아니다.
2-2. Case 2
$ aws ec2 describe-nat-gateways --query 'NatGateways[].[NatGatewayAddresses[*].PrivateIp,NatGatewayId]' --output text | sed '$!N;s/\n/ /'
결과: 실패
NatGatewayAddresses[*].PrivateIp도 마찬가지로 Private IP 목록을 반환한다. NAT Gateway ID는 스칼라 값인데 Private IP는 리스트 형태가 되므로, 두 값을 같은 레벨의 컬럼처럼 출력하기 어렵다.
2-3. Case 3
$ aws ec2 describe-nat-gateways --query 'NatGateways[].[NatGatewayAddresses[0].PrivateIp,NatGatewayId]' --output text | sed '$!N;s/\n/ /'
결과: 절반의 성공. 한 라인에 두 묶음의 결과가 나왔다.
NatGatewayAddresses[0].PrivateIp처럼 첫 번째 요소를 지정하면 Private IP가 리스트가 아니라 단일 값으로 내려온다. 이때부터는 PrivateIp와 NatGatewayId가 같은 레벨의 값이 되므로 원하는 출력에 가까워진다. 다만 뒤에 붙인 sed가 줄을 강제로 합치면서, 여러 NAT Gateway 결과가 있을 때 서로 다른 레코드까지 한 줄로 이어질 수 있다.
2-4. Case 4
$ aws ec2 describe-nat-gateways --query 'NatGateways[].[NatGatewayAddresses[0].PrivateIp,NatGatewayId]' --output text
결과: 성공. 그러나 왜인지 찜찜했다.
정리하면, 이 경우에는 sed가 필요 없었다. --query에서 이미 [PrivateIp, NatGatewayId] 형태의 리스트를 만들고 있기 때문에 --output text는 리스트의 순서를 유지해서 출력한다.
3. 정리
원하는 순서로 텍스트 출력을 얻고 싶다면, 객체 형태보다 리스트 형태로 명시하는 편이 안전하다. 예를 들어 아래처럼 쓰면 첫 번째 Private IP와 NAT Gateway ID를 순서대로 출력할 수 있다.
$ aws ec2 describe-nat-gateways --query 'NatGateways[].[NatGatewayAddresses[0].PrivateIp,NatGatewayId]' --output text
주의할 점은 NatGatewayAddresses[0]가 말 그대로 첫 번째 주소만 선택한다는 것이다. NAT Gateway에 연결된 주소가 여러 개일 가능성까지 고려해야 한다면, 첫 번째 값만 뽑아도 되는지 먼저 확인해야 한다.
추가로, --output text에서 객체를 사용할 때는 키 이름 기준으로 출력 순서가 달라질 수 있다. 출력 순서가 중요하다면 다음처럼 리스트를 사용해 컬럼 순서를 직접 지정하는 방식이 낫다.
--query 'NatGateways[].[NatGatewayAddresses[0].PrivateIp,NatGatewayId]'
결론: 이번 문제의 핵심은 sed가 아니라 JMESPath 쿼리에서 리스트와 단일 값을 어떻게 다루느냐였다.