run-instance명령어에서 DisableApiTermination와 DeleteOnTermination 옵션의 차이점에 대해서 알아봤습니다.

2021.12.14

안녕하세요, 임채정입니다.
이번에 안건에서 EC2 인스턴스를 구축했습니다.
AWS CLI를 사용해 구축을 했는데 처음 사용해봐서 그런지 명령어를 정리할 때 조금 헷갈리는 부분이 있었습니다.
그 중에서도 DisableApiTermination와 DeleteOnTermination의 옵션이 특히 헷갈렸기 때문에 이번 블로그에서는 2개의 옵션이 뭐가 다른지 또한 어떤 역할을 하는지 정리하고자 합니다.

アジェンダ

  1. DisableApiTermination
  2. DeleteOnTermination
  3. 마무리 (참고 페이지)

1. DisableApiTermination

먼저 DisableApiTermination 옵션에 대해 알아 봅시다.

명령어의 정의

DisableApiTermination의 의미를 그대로 번역하면 Api 종료 사용 안 함 입니다.
즉, EC2 인스턴스를 종료하지 않도록하는 삭제 보존 기능입니다.

  • AWS Management Console, CLI, API를 사용하는 타인의 실수로 인스턴스가 종료되는 것을 방지
  • 각 인스턴스는 DisableApiTermination 속성을 가지고 있으며 그 기본 값은 false로 설정
  • 인스턴스가 실행 중이거나 중단된 상태에 있을 때 설정 변경 가능

사용법

run-instances 명령어의 옵션으로 사용합니다.

aws ec2 run-instances \
--disable-api-termination

실제로 옵션을 추가한 아래의 명령어를 실행해서 테스트해보겠습니다.
인스턴스를 구분해주기 위해 Name 태그에 DisableApiTermination을 넣어주겠습니다.

aws ec2 run-instances \
--instance-type t2.micro \
--image-id (AMI ID) \
--subnet-id (SubnetID) \
--security-group-ids (SecurityGroupID) \
--key-name (키페어 이름) \
--region ap-northeast-1 \
--count 1\
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=DisableApiTermination}]' \
--disable-api-termination

명령어를 실행하고 EC2가 만들어지면 인스턴스 목록을 출력해주는 명령어를 실행해서 만든 인스턴스를 확인해 보겠습니다.
결과를 보면 Name이 DisableApiTermination인 인스턴스가 잘 만들어졌습니다.

aws ec2 describe-instances --output table \
--query 'Reservations[*].Instances[].{
  ID: InstanceId,
  Name: Tags[?Key==`Name`] | [0].Value,
  State: State.Name
  }'
  
----------------------------------------------------------------
|                       DescribeInstances                      |
+----------------------+-------------------------+-------------+
|          ID          |          Name           |    State    |
+----------------------+-------------------------+-------------+
|  i-03937a62ff3e24d54 |  DisableApiTermination  |  running    |
+----------------------+-------------------------+-------------+

이번에는 DisableApiTermination 속성이 잘 적용되어 있는지 한 번 삭제해보겠습니다.
삭제 명령어를 실행해보면 아래와 같이 에러 메시지가 나와있는 것을 확인할 수 있습니다.

aws ec2 terminate-instances --instance-ids i-03937a62ff3e24d54

An error occurred (OperationNotPermitted) when calling the TerminateInstances operation: The instance 'i-03937a62ff3e24d54' may not be terminated. 
Modify its 'disableApiTermination' instance attribute and try again.

에러 메시지를 보면 종료를 실행할지 없었고 인스턴스를 종료하고 싶으면 DisableApiTermination 속성을 변경하라고 나와있습니다. 이 것으로 DisableApiTermination 속성이 인스턴스의 삭제 보존을 해주는 옵션인 것을 알 수 있습니다.

그럼 이번에는 실제로 삭제를 해보겠습니다.
먼저 DisableApiTermination 속성을 변경하겠습니다.

aws ec2 modify-instance-attribute \
--instance-id i-03937a62ff3e24d54 \
--no-disable-api-termination

변경되고 나서 변경된 걸 확인 하기 위해 DisableApiTermination 속성의 설정을 확인해줍니다.

aws ec2 describe-instance-attribute --instance-id i-03937a62ff3e24d54  \
--attribute disableApiTermination  \
--query "[InstanceId,DisableApiTermination.Value]" --output text

# i-03937a62ff3e24d54     False

그리고 아까 실패했던 삭제 명령어를 입력해주면 성공적으로 삭제가 됩니다.

aws ec2 terminate-instances --instance-ids i-03937a62ff3e24d54

{
    "TerminatingInstances": [
        {
            "CurrentState": {
                "Code": 32,
                "Name": "shutting-down"
            },
            "InstanceId": "i-03937a62ff3e24d54",
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}

마지막으로 EC2 인스턴스의 목록을 확인하면 제대로 삭제 된 것을 확인할 수 있습니다.

aws ec2 describe-instances --output table \
--query 'Reservations[*].Instances[].{
  ID: InstanceId,
  Name: Tags[?Key==`Name`] | [0].Value,
  State: State.Name
  }'

----------------------------------------------------------------
|                       DescribeInstances                      |
+----------------------+-------------------------+-------------+
|          ID          |          Name           |    State    |
+----------------------+-------------------------+-------------+
|  i-03937a62ff3e24d54 |  DisableApiTermination  |  terminated |
+----------------------+-------------------------+-------------+

2. DeleteOnTermination

명령어의 정의

영어의 의미를 그대로 번역하면 종료 시 삭제 입니다.
번역의 의미로만 봤을 때도 위의 명령어와 다른 점이 보이시나요?
위의 명령어는 삭제를 안하는거고 DeleteOnTermination는 삭제를 한다는 의미입니다.
또한 DeleteOnTermination 속성의 경우 EC2 인스턴스의 옵션이라기 보다는 EBS 볼륨이나 Network Interfaces 를 정의 할 때 들어가는 옵션입니다.
즉, 인스턴스를 종료할 때 EBS 볼륨 혹은 Network Interfaces를 같이 종료할지에 대해 물어보는 겁니다.

좀 더 자세하게 정의해보겠습니다.

  • Amazon EBS 루트 디바이스 볼륨은 기본적으로 인스턴스 종료 시 자동으로 삭제
  • 시작 시 연결하는 추가 EBS 볼륨 또는 기존 인스턴스에 연결하는 EBS 볼륨은 인스턴스가 종료된 후에도 기본적으로 유지되지만 DeleteOnTermination 속성으로 변경 가능
  • 루트 외 EBS 볼륨을 인스턴스에 연결하면 DeleteOnTermination 속성은 false가 기본 설정

사용법

aws ec2 run-instances \
--block-device-mappings “[{\“DeviceName\“:\“//dev/sda1\“,\“Ebs\“:{\“VolumeSize\“:100,\“DeleteOnTermination\“:false}}]”

실제로 옵션을 추가한 명령어를 사용해보겠습니다.
일단 루트 디바이스 볼륨일때는 DeleteOnTermination가 기본 true로 설정되어 있기 때문에 실제로 실행은 생략하겠습니다.

DeleteOnTermination이 false 인 명령어를 실행해보겠습니다.

aws ec2 run-instances \
--instance-type t2.micro \
--image-id (AMI ID) \
--subnet-id (SubnetID) \
--security-group-ids (SecurityGroupID) \
--key-name (키페어 이름) \
--count 1 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=DeleteOnTermination}]' \
--block-device-mappings "[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"VolumeSize\":8,\"DeleteOnTermination\":false}}]"

EC2 인스턴스가 잘 만들어졌으면 이번에는 EC2 인스턴스를 삭제해서 EBS볼륨이 어떻게 되는지 보겠습니다.

aws ec2 terminate-instances --instance-ids i-048941e484383e63f

{
    "TerminatingInstances": [
        {
            "CurrentState": {
                "Code": 48,
                "Name": "terminated"
            },
            "InstanceId": "i-048941e484383e63f",
            "PreviousState": {
                "Code": 80,
                "Name": "stopped"
            }
        }
    ]
}

확인해보면 인스턴스는 잘 삭제 되었습니다.

aws ec2 describe-instances --output table \
--query 'Reservations[*].Instances[].{
  ID: InstanceId,
  Name: Tags[?Key==`Name`] | [0].Value,
  State: State.Name
  }'

----------------------------------------------------------------
|                       DescribeInstances                      |
+----------------------+-------------------------+-------------+
|          ID          |          Name           |    State    |
+----------------------+-------------------------+-------------+
|  i-048941e484383e63f |  DeleteOnTermination    |  terminated |
+----------------------+-------------------------+-------------+

하지만 인스턴스와 연결되어 있던 EBS 볼륨은 삭제 되지 않고 남아 있는 것을 확인할 수 있습니다.

aws ec2 describe-volumes --output table \
--query 'Volumes[].{ID:VolumeId, Type:VolumeType, Size:Size}'

-------------------------------------------
|             DescribeVolumes             |
+------------------------+-------+--------+
|           ID           | Size  | Type   |
+------------------------+-------+--------+
|  vol-06c6b49fff62a9df3 |  8    |  gp2   |
+------------------------+-------+--------+

여기서 주의할 점은 DeleteOnTermination 값을 실수로 false로 설정해둬서 EBS 볼륨을 삭제하지 않으면 계속 남아있으면서 요금이 발생할 수 있습니다.
그렇기 때문에 잊지 않고 EBS 볼륨을 삭제해주도록 하겠습니다.

aws ec2 delete-volume --volume-id vol-06c6b49fff62a9df3

3. 마무리 (참고 페이지)

EC2 인스턴스 종료