[ AWS ] EC2 직렬 콘솔에서 응급모드 진입 설정 – Amazon Linux 2

리눅스에서 패스워드 리셋이나 마운트 에러 등의 이슈로 응급 모드로 진입하여 작업해야 할 때가 있는데 AWS는 기본적으로 원격 관리이기 때문에 콘솔 화면이 보이지 않습니다.

Nitro Hypervisor 를 지원하는 T3 급 이상의 인스턴스는 AWS Console 에서 직접 시리얼 콘솔을 접근할 수 있는 옵션이 추가가 되었는데

GRUB Timeout 설정 시간이 짧아서 응급모드 진입이 어려운 이슈가 있습니다.
Amazon Linux 2 OS 의 GRUB 타임아웃 시간을 늘려서 확인할 수 있도록 해 봅니다.

마운트 실패로 인한 응급 모드의 큰 틀은 다음의 2가지로 분류가 됩니다.

1) GRUB TIMEOUT 변경
2) 응급 모드 진입 후 mount 옵션에 nofail 추가 시, 실패해도 진행 가능

IAM 접근 최소 조건

# IAM이 Administrator Group 이라면 상관 없으나, 디테일 권한 관리될 경우
다음의 정책을 추가합니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:GetSerialConsoleAccessStatus",
                "ec2:EnableSerialConsoleAccess",
                "ec2:DisableSerialConsoleAccess"
            ],
            "Resource": "*"
        }
    ]
}

GRUB TIMEOUT 값 수정하기

# root 권한에서 Default GRUB 의 값을 수정 및 추가합니다.
Console Serial 은 root 패스워드가 콘솔 로그인 가능해야 합니다. 
아마존의 타임아웃 권장값은 1입니다만 넉넉하게 10(초)로 변경합니다. 

sed -i 's/GRUB_TIMEOUT=0/GRUB_TIMEOUT=10/g' /etc/default/grub
sed -i 's/GRUB_TERMINAL="ec2-console"/GRUB_TERMINAL="console serial"/g' /etc/default/grub
 echo -e GRUB_SERIAL_COMMAND=\"serial --speed=115200\" >> /etc/default/grub

# check
cat /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295 rd.emergency=poweroff rd.shell=0"
GRUB_TIMEOUT=10
GRUB_DISABLE_RECOVERY="true"
GRUB_TERMINAL="console serial"
GRUB_X86_USE_32BIT="true"
GRUB_SERIAL_COMMAND="serial --speed=115200"

# 실제 GRUB 에 적용합니다
grub2-mkconfig -o /boot/grub2/grub.cfg

EC2 Reboot 후 직렬 콘솔 확인

10초 지연 후 지나가므로 e 키를 바로 눌러 응급모드 진입

응급모드 진입

# 해당 위치에 single 구문을 추가 후 Ctrl + x 로 부팅

FSTAB 에서 nofail 옵션 사용

# 추가 마운트 옵션에 nofail 을 넣으면 부팅 시 실패해도 정상 진행됩니다



[ AWS ] Cloud-init SSH RootPassword 세팅하기

AWS 의 Amazon-Linux OS 로 생성한 이미지 등의 경우 기본적으로 Password 방식의 로그인이 허용되어 있지 않으며, ssh 설정에서 주석처리를 해제하여도 이미지 백업 후 복원 시 Cloudinit 에 의해 다시 주석이 잠기는 보안성이 존재합니다.

이는 다량의 작업을 해야 할 때 번거로움으로 작용할 수 있는데
패스워드 로그인을 허용하는 방법은 2가지로 구분할 수 있습니다.

  1. 이미지에서 인스턴스 생성 시에 Advance의 User-data 에서 리눅스 스크립트로 부팅 시 root 잠금 해제
  2. 기존 이미지에서 Cloudinit Config 의 설정 변경
# 이미지에서 인스턴스 생성 시 다음의 스크립트를 추가한다.

# sshd Permitrootlogin 
sed -i 's/#PermitRootLogin yes/PermitRootLogin yes/g' /etc/ssh/sshd_config
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config

# Key root account permit
sed -i 's/^.*10" //g' /root/ssh/authorized_keys

# set root password
echo "P@ssw0rd" | passwd root --stdin 

# sshd restart
systemctl restart sshd

이미지에서 인스턴스 생성 시 User-data 추가

생성 후 직렬 콘솔을 통해 root password 로그인이 가능하다.

이미지 생성 시에 리셋되지 않도록 하려면 Cloudinit 설정을 변경한다

disable_root : true --> false ( 0 ) 
ssh_pwauth:  false --> true ( 1 ) 



[AWS] Lambda + EventBridge 를 통한 RDS 데이터베이스를 자동으로 중지 및 실행하기

RDS 인스턴스는 DB 인스턴스 시간, 프로비저닝된 스토리지, 백업 스토리지, I/O 요청, 프로비저닝된 IOPS 및 데이터 전송에 대해 청구됩니다. 사용하지 않는 리소스들을 중지하지 않을 경우 지속적으로 비용이 발생하며 이 문서에서는 Amazon EventBridgeAWS Lambda의 조합을 사용하여 일정에 따라 모든 지역에 대하여 미사용 RDS 인스턴스를 중지/시작하기 위한 자동화된 솔루션을 구현하는 방법을 살펴보겠습니다.

dbblog_1100-01

단계 :

1. 사전 구성

2. IAM 정책 및 역할 생성

3. Lambda 함수 생성

4. EventBridge 규칙 생성

5. 테스트

 

1. 사전 구성

AWS 서비스에 프로그래밍 방식으로 연결하려면 엔드포인트를 사용해야 합니다.

그러나 일부 리전(opt-in)들은 기본적으로 비활성화 되어 있으며 해당 리전들의 DB 인스턴스 정보를 가져오기 위해선 활성화를 진행해주어야 합니다.

opt-in region

  • 아프리카(케이프타운)

  • 아시아 태평양(홍콩)

  • 유럽(밀라노)

  • 중동(바레인)

  • 아시아 태평양(자카르타)

 

  1. 권한이 있는 계정으로 콘솔에 로그인 후 우측 상단 계정 선택 – 계정 – AWS 리전 비활성화 되어있는 5개의 리전들을 활성화 상태로 변경합니다.

사전1

비활성화리전

 

  1. 테스트를 진행할 DB 인스턴스를 생성합니다. 총 3개 리전에 대하여 테스트 해보겠습니다.

홍콩 : MariaDB

오사카 : AWS Aurora

서울 : Mysql

HONGKONG1

OSAKA1

Seoul1

 

2. IAM 정책 및 역할 생성

 

  1. RDS Stop/Start 역할을 위한 정책을 생성합니다. IAM 콘솔에서 정책 – 정책 생성

iam1

 

  1. JSON 편집기에서 IAM 권한을 연결합니다.

iam2

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "rds:StartDBCluster",
                "rds:StopDBCluster",
                "rds:ListTagsForResource",
                "rds:DescribeDBInstances",
                "rds:StopDBInstance",
                "rds:DescribeDBClusters",
                "rds:StartDBInstance"
            ],
            "Resource": "*"
        }
    ]
}


  1. RDS-Stop-Start-Policy 이름 입력 후 정책 생성을 클릭합니다.

iam3

 

  1. RDS Stop/Start 를 위한 역할을 생성합니다. IAM 콘솔에서 역할 – 역할 만들기

iam4

 

  1. AWS Lambda를 신뢰할 수 있는 엔터티로 선택 후 다음을 클릭합니다.

iam5

 

  1. 생성한 정책 RDS-Stop-Start-Policy 필터링 후 선택 – 다음을 클릭합니다.

iam6

 

  1. RDS-Stop-Start-Role 이름 입력 후 역할 생성을 클릭합니다.

iam7


3. Lambda 함수 생성

AWS Lambda 함수를 생성하여 RDS DB 인스턴스를 Stop 시키도록 하겠습니다.

Region은 어느 지역이던 상관 없으나 여기선 서울 Region에 생성해보겠습니다.

 

  1. RDS 인스턴스를 Stop할 Lambda 함수를 생성합니다. Lambda 콘솔 함수 – 함수 생성

lambda1

 

  1. 다음과 같이 입력 후 함수를 생성합니다.

함수 이름 : StopRDS

런타임 : Python 3.9

권한 : 기본 실행 역할 변경 – 기존 역할 사용 – 생성한 역할 RDS-Stop-Start-Role 선택

lambda2

 

  1. Boto3, Botocore를 이용하여 Python 코드 작성을 진행합니다.
Boto : AWS에서 Python 프로그래밍 언어의 사용을 개선하도록 설계뙨 소프트웨어 개발 키트(SDK) 이며 가장 최신 버전인 Boto3 까지 나와있습니다.

Botocore : AWS 도구에 대해 기본적인 액세스를 제공하며 low-level의 클라이언트 요청을 만들고 API에서 결과를 가져옵니다.

lambda3

# StopRDS 함수 코드

import boto3
import botocore

# get all regions
available_regions = boto3.Session().get_available_regions('rds')

def lambda_handler(event, context):

    for region in available_regions:
        rds = boto3.client('rds', region_name=region)


      # Define instances
        instances = rds.describe_db_instances()

        stopInstances = []


      # stop instances.
        for db in instances["DBInstances"]:

            try:
                stopInstances.append(db["DBInstanceIdentifier"])
                rds.stop_db_instance(DBInstanceIdentifier=db['DBInstanceIdentifier'])
            except botocore.exceptions.ClientError as err:
                print(err)

        # get all aurora db clusters
        rds_aurora = rds.describe_db_clusters()

        # stop all aurora cluster
        for aurora_cluster in rds_aurora['DBClusters']:
            try:
                rds.stop_db_cluster(DBClusterIdentifier=aurora_cluster['DBClusterIdentifier'])
            except botocore.exceptions.ClientError as err:
                print(err)


     # print  all instances that will stop.
    if len(stopInstances) > 0:
       print ("stopInstances")
    else:
       print ("No rds instances to shutdown.")

stop_db_instance API는 Aurora 클러스터의 일부인 인스턴스를 종료할 수 없기 때문에 별도로 Aurora DB에 대하여 stop_db_cluster API 호출을 해주어야 합니다.

StartRDS 함수 작성을 하고자 할 경우 아래 코드를 입력하여 함수를 생성하면 됩니다.

# StartRDS 함수 코드

import boto3
import botocore

# get all regions
available_regions = boto3.Session().get_available_regions('rds')

def lambda_handler(event, context):

    for region in available_regions:
        rds = boto3.client('rds', region_name=region)


      # Define instances
        instances = rds.describe_db_instances()

        startInstances = []


      # start instances.
        for db in instances["DBInstances"]:

            try:
                startInstances.append(db["DBInstanceIdentifier"])
                rds.start_db_instance(DBInstanceIdentifier=db['DBInstanceIdentifier'])
            except botocore.exceptions.ClientError as err:
                print(err)

        # get all aurora db clusters
        rds_aurora = rds.describe_db_clusters()

        # stop all aurora cluster
        for aurora_cluster in rds_aurora['DBClusters']:
            try:
                rds.start_db_cluster(DBClusterIdentifier=aurora_cluster['DBClusterIdentifier'])
            except botocore.exceptions.ClientError as err:
                print(err)


     # print  all instances that will stop.
    if len(startInstances) > 0:
       print ("startInstances")
    else:
       print ("No rds instances to start.")

 

4. EventBridge 규칙 생성

 

  1. Amazon EventBridge 콘솔에서 규칙 – 규칙 생성을 클릭합니다.

eventbridge0

 

  1. 규칙 세부 정보에서 RDS_Instances_Stop 규칙 이름으로 입력 및 규칙 유형 일정 선택 후 다음을 클릭합니다.

eventbridge4

 

  1. Cron 표현식을 작성합니다. 0 9 * * ? *

아래는 매일 오후 6시에 Lambda 함수를 트리거하는 표현식입니다.

자세한 cron 표현식은 공식 문서에 잘 나와 있습니다.

https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/services-cloudwatchevents-expressions.html

eventbridge5

 

  1. AWS 서비스 선택 후 StopRDS 함수를 대상으로 지정한 뒤 다음을 클릭합니다.

eventbridge6

 

  1. EventBridge 규칙이 정상적으로 생성되었습니다.

eventbridge8

 

5. 테스트

생성한 Lambda 함수, EventBridge 규칙으로 3개 Region DB 들에 대하여 테스트를 진행해보겠습니다.

 

  1. Amazon Lambda 콘솔에서 StopRDS 선택 후 테스트를 클릭, StopTest 이름을 작성한 뒤 기본 템플릿 hello-world 로 저장합니다.

Test1

 

  1. 저장된 템플릿 에서 테스트를 클릭합니다.

Test2

 

  1. 테스트가 정상적으로 성공했다면 다음과 같은 화면을 볼 수 있습니다.

Test3

 

  1. 이제 3개 리전에 대한 RDS 데이터베이스를 확인해보겠습니다.

HONGKONG2

OSAKA2

Seoul2

서울 리전 Mysql 인스턴스, opt-in 리전인 홍콩 Mssql 정상적으로 Stop 되고 있으며 오사카 리전 Aurora DB Cluster도 정상적으로 Stop 중인 상태를 확인할 수 있습니다.

감사합니다.




[AWS] Route53 + Workmail + SES 를 통한 메일 서비스 사용

 


목 차

  1. 무료 도메인 구매
  2. route53 호스팅영역 추가
  3. Workmail 생성
    1. Workmail Add Domain
    2. Domain record 추가
    3. Workmail user 생성
    4. Workmail Test

    무료 도메인 구매

    [링크] https://my.freenom.com/clientarea.php

    무료 도메인 사이트로 무난해 보이는 “freenom” 선택

    <사항>
    1. 사용 가능TLD 가 제한적 => (.tk, .ml, .ga, .gq, .cf)
    2. 연장 시기 놓치면 유료화 - 발급밭은 도메인은 최대 1년 단위연장해, 연장은 만료로부 2주 안에 신청 가능
    3. 인기있는 도메인 강제 하이재킹 - 인기가 높아지면 접속량도 증가하며, freenom에서는 트래픽 모니터링을 하여 실제 트래픽이 많아진 도메인은 강제유료전환
    4. 제한적인 DNS 서버 - 국내 DNS 서버의 경우 Freenom 도메인 정보가 공유되지 않아 국내 환경에서는 접속이 어려워지는 현상이 발생하기도 함.
    위 주사항에도 테스트 용도로는 문제 없기에 도메인 구매 진행함.
    
    1. freenom 가입
    2. domain 발급
       1) [Register a new Domain] 을 선택 후 원하는 도메인 이름 검색
       2) 원는 TLD 오른쪽에 [Get it now!] 클릭하여 Selected 후에 Checkout 버튼 클릭
       3) [Use DNS] - Use Freenom DNS Service 에서 IP address 작성  ==>  Domain과 매칭 될 IP 작성
       4) Total Due Today : $0.00USD   비용 확인 -> 약관 동의 -> Complete Order 클릭하여 구매

    Route53 호스팅 영역 추가

    route 53 – 호스팅 영역 – 호스팅 영역 생성

    1. 도메인 이름 : <freenom에서 구입주소>
    2. 유형 - 블릭 스팅 영역 체크(외부 사용하기 위함.)
    3. 호스팅 영역 생성 클릭

    WorkMail 생성

    Workmail – Create organization

    1. Create organization
    2. Email domain : Existing Route 53 domain
        - Route 53 hosted zone : <Freenom에서 구입주소>
    3. Alias : alias name 작성
        - 별칭은 Workmail 웹 어플리케이션에 엑세스 할 url에 사용됨.(https://<alias>.awsapps.com/mail)
    4. Advanced settings
        - User directory : 
           1) Create Amazon Workmail directory - 사용할 디렉토리가 존재하지 않을 경우 Workmail사용할 디렉토리 생성
           2) Use existing directory - AWS Directory Servise 사용하여 생성 된 Simple AD, 관리형 AD, AD 커넥터 사용중이며, workmail가 관리대상 경우 당 디렉토리 선택
        - Encryption :
           1) use Amazon WorkMail managed key - AWS 관리되는 키 선택하며, 직접 관리되지 않음
           2) Use existing customer managed key(CMK) - AWS KMS 에서 customer managed key(CMK) 생성key 사용
    5. Create organization 클릭

    Workmail Add Domain

    WorkMail-Organizations-<생성한 organization>-Domains

    1. Add domain 클릭
    2. Domain name - route53에 등록되있는 domain 선택 후 생성
    3. 도메인 안에 레코드 값 확인
        - Domain ownership : 도메인을 소유하고 있음을 인증하는 TXT 레코드 
        - WorkMail configuration : Workmail용 MX, CNAME 레코드
        - Improved security : 제대로된 도메인 이는 것 인증하는 레코드들(DKIM, SPF, DMARC)
        - Improved email delivery 4. Organization - Domains 에서 [my domain] 체크 후 "Set as default" 클릭하여 default 도메인을 [my domain]으로 변경

    Domain record 추가

    Route 53 – 호스팅 영역 – <개인 도메인> – 레코드 – 레코드 생성

    1. subdomain 작성(main domain 일 경우 작성 X)
    2. 레코드 Type 선택하기(TXT, MX, CNAME..)
    3. 레코드의 값 작성
        ** 위 "Workmail Add Domain" 의 3번과 동일한 값을 추가 **

    Workmail User 생성

    Workmail – organization – Users

    User details
    1. User name - user name을 이용해서 AWS WorkMail 웹메에 로그 가능함.
    2. Display name - 시스상 표시되는 name
    
    Email setup
    1. Email address
        - <User name>@<workmail 도메인>
    2. Password , Repeat password
        - Email 접속시 필요비밀번호

    Workmail Test

    
    <Mail login>
    1. WorkMail - Organizations - [my organization] 에서 아래에 url 주소로 접속 
        - https://xxx.awsapps.com/mail
    2. Workmail user 이름(Email address 이름은 x), user 비밀번호 작성하여 로그인

    <발신>

    <수신>




    Amazon Elastic Container Registry Public (ECR Public)

    Amazon Elastic Container Registry Public (ECR Public) 사용해보기

     

    개요

    Amazon Elastic Container Registry(Amazon ECR)는 안전하고 확장 가능하고 신뢰할 수 있는 AWS 관리형 컨테이너 이미지 레지스트리 서비스 입니다.
    Amazon ECR은 AWS IAM을 사용하여 리소스 기반 권한이 있는 퍼블릭/프라이빗 이미지 리포지토리를 지원 합니다.
    따라서 AWS 제공하는 ECS, EKS등에서 ECR을 쉽게 엑세스 할 수 있습니다.

     

    요금

    https://aws.amazon.com/ko/ecr/pricing/

    • Docker Hub와 환경 및 비용등 고려 필요
      • https://www.docker.com/pricing/

    Service Quotas

    https://us-west-1.console.aws.amazon.com/servicequotas/home/services/ecr/quotas

     

    Amazon ECR Public Gallery

    https://gallery.ecr.aws/

    Amazon ECR 공개 갤러리는 Amazon ECR 공개 리포지토리에서 호스팅되는 컨테이너 이미지를 찾고 공유할 수 있는 공개 웹 사이트입니다. 

     

    사용자 추가

     

    자격 증명 설정

    • AWS CLI 설치
      • https://docs.aws.amazon.com/ko_kr/cli/v1/userguide/cli-chap-install.html
      • 운영 환경에 맞는 지침 참고

    퍼블릭 리포지토리 생성

     

    Push

    ecr-public endpoints

    • AWS CLI 또는 AWS SDK 사용할 때 권장

    제공되는 명령어를 참고하여 진행한 예제.

    • 인증 토큰을 검색하고 레지스트리에 대해 Docker 클라이언트를 인증

     

    • 이미지에 태그를 지정

       

    • AWS 리포지토리로 푸시

     

    pull

     

     




    Lambda, Cloudwatch를 활용하여 ec2 stop/start 스케줄 설정하기

    Lambda 란 ?

    서버리스 컴퓨팅 서스로, 애플리케이션을 실행하기 위해 별도의 서버 셋업 없이 곧바코드 실행주는 서비스 이다.
    초 단위로 비용을 계산하는 ec2와는 별개Lambda는 1ms 당 요금을 계산해 정확히 사용용이 발생한다.

    1. Lambda 에 붙일 IAM 정책 및 역할 생성

    **정책 및 역할을 연결하지 않고 Lambda를 바로 생성했을 경우에는 정책 및 역할이 자동 생성된다.

    [Policy]

    정책 이름 : Lambda_policy
    
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "ec2:Describe*",
                    "ec2:Start*",
                    "ec2:Stop*"
                ],
                "Resource": "*"
            }
        ]
    }

    [Role]

    역할 이름 : Lambda_role
    
    생성한 policy(Lambda_policy)추가

    2. Lambda 생성

    Auther from scratch 선택
    Lambda Function 이름 : StartEC2Instance / StopEC2Instance
    Runtime : Python3.8
    Permissions - Use an existing role - 생성해두었던 role 선택

    [Lambda Code]

    import boto3
    region = 'ap-northeast-2'
    instances = []
    ec2_r = boto3.resource('ec2')
    ec2 = boto3.client('ec2', region_name=region)
    //
    for instance in ec2_r.instances.all():
        instances.append(instance.id)
    
    def lambda_handler(event, context):
        ec2.start_instances(InstanceIds=instances)
        print('started your instances: ' + str(instances))

    태그를 설정하여 특정 ec2에만 스크립트 적용될 수 있도록 할수도 있습니다.

    import boto3
    region = 'ap-northeast-2'
    instances = []
    ec2_r = boto3.resource('ec2')
    ec2 = boto3.client('ec2', region_name=region)
    
    for instance in ec2_r.instances.all():
        for tag in instance.tags:
            if tag['Key'] == 'auto-schedule':
                if tag['Value'] == 'auto':
                    instances.append(instance.id)
    
    def lambda_handler(event, context):
        ec2.start_instances(InstanceIds=instances)
        print('start your instances: ' + str(instances))

    정상적으로 스크립트가 구동되는지 테스트를 해봅시다.

    Lambda - Deploy - Test
    구동이 제대로 안된다면,
    1) IAM Policy, Lambda code 확인
    2) Lambda-General configuration - Timeout 을 3(default) -> 15로 변경.
    3) 지정한 region에 있는 ec2의 Instance state가 1EA라도 terminate 되어있는 상태라면 스크립트가 구동되지 않음.

    3. CloudWatch 스케줄링 등록

    Event - Rules - Go to Amazon EventBridge
    
    step1)
    규칙 이름 : StartEC2Instance 
    Event bus : default
    Rule type : Schedule
    
    step2)
    GMT 기준 cron 표현식으로 원하는 시간 지정
    
    step3)
    target types : AWS service
    Select a target : Lambda function
    Function : Lambda Function 선택 (StartEC2Instance)
    ++ 타겟 추가 가능 
    
    step4) 
    태그 설정

    (선택) 4. Lmabda code 성공/실패 메일 알람

    [SNS]

    topic 생성
    subscription 생성
        Protocol : Email 
        Endpoint : 수신받을 이메일 지정

    [Lambda]

    Configuration - Destinations - Add destination 
    source : Asynchronous invocation
    Condition : On Failure / On Success 
    Destination Type : SNS topic
    Destination : 생성한 topic 선택



    AWS SSM 을 통한 VPC Private Network 접근

    목적

    - VPC 내의 Private Network 에 외부 공인 대역에서 Shell 로 접근 ( VPN 역할 )

    특징

    - SSM 을 통해 AWS 연결을 하는 것으로, IGW 나 EIP 등의 VPC내 별도 제약이 필요없다
    - EC2 SSH 접근 용도의 Password 나 Key-Pair 가 필요없다.
    - Shell 전환으로 SSH 와 거의 동일하게 사용할 수 있다.
    - AWS Client VPN 과 비교 시, 비용적으로 유리하다.
    

    요구사항

    - AWS CLi 를 설치 및 AWS 리소스에 접근할 수 있는 공인망 환경 ( VM / CT / Server )
      일부 리전의 경우 AWS Console 내에서 Cloudshell 사용 가능  

    설치 순서

    • 1) Private Network 에 접근할 수 있는 IAM 권한 설정
    • 2) EC2 에 IAM Role 추가
    • 3) EC2 에 SSM Agent 설치
    • 4) AWS CLI 를 통한 EC2 연결
    1. Key 방식 전용의 IAM 생성 후 권한 설정

    – 관리형 정책을 만들어서 IAM 에 할당한다.

    arn 은 리전과 어카운트와 접근할 EC2 ID 를 적는다

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "ssm:StartSession"
                ],
                "Resource": [
                    "arn:aws:ec2:us-west-2:1234567890:instance/i-ahe52134fxed6"
    
                ]
            },
            {
                "Effect": "Allow",
                "Action": [
                    "ssm:TerminateSession"
                ],
                "Resource": [
                    "arn:aws:ssm:*:*:session/${aws:username}-*"
                ]
            }
        ]
    }

    2. IAM Custom Role 을 생성한 후 VPC 내의 EC2 에 설정한다

    – Role 은 SSM InstanceCore 만 선택
    – Role Name 지정 후 생성

    EC2 의 보안 설정에서 해당 롤을 추가한다

    3. EC2 에 SSM-Agent 를 설치한다

    Aamazon 2 리눅스 인스턴스의 경우에는 기본 설정되어 있을 수 있다.
    [root@ip-10-10-20-201 ~]# sudo yum install -y https://s3.region.amazonaws.com/amazon-ssm-region/latest/linux_amd64/amazon-ssm-agent.rpm
    Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
    Cannot open: https://s3.region.amazonaws.com/amazon-ssm-region/latest/linux_amd64/amazon-ssm-agent.rpm. Skipping.
    Error: Nothing to do
    [root@ip-10-10-20-201 ~]# wget https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
    --2022-03-29 02:49:06--  https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
    Resolving s3.amazonaws.com (s3.amazonaws.com)... 52.217.196.240
    Connecting to s3.amazonaws.com (s3.amazonaws.com)|52.217.196.240|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 26724168 (25M) [binary/octet-stream]
    Saving to: ‘amazon-ssm-agent.rpm’
    
    100%[==================================================================================================>] 26,724,168  12.7MB/s   in 2.0s
    
    2022-03-29 02:49:08 (12.7 MB/s) - ‘amazon-ssm-agent.rpm’ saved [26724168/26724168]
    설치 후 자동시작 활성화한다.
    [root@ip-10-10-20-201 ~]# rpm -Uvh amazon-ssm-agent.rpm
    warning: amazon-ssm-agent.rpm: Header V4 RSA/SHA1 Signature, key ID 693eca21: NOKEY
    Preparing...                          ################################# [100%]
    Updating / installing...
       1:amazon-ssm-agent-3.1.1080.0-1    ################################# [100%]
    Created symlink from /etc/systemd/system/multi-user.target.wants/amazon-ssm-agent.service to /etc/systemd/system/amazon-ssm-agent.service.
    [root@ip-10-10-20-201 ~]# systemctl enable amazon-ssm-agent
    [root@ip-10-10-20-201 ~]# systemctl start amazon-ssm-agent
    
    
    
    [root@ip-10-10-20-201 ~]# systemctl status amazon-ssm-agent
     -- amazon-ssm-agent.service - amazon-ssm-agent
       Loaded: loaded (/etc/systemd/system/amazon-ssm-agent.service; enabled; vendor preset: enabled)
       Active: active (running) since Tue 2022-03-29 02:53:54 UTC; 21s ago
     Main PID: 3355 (amazon-ssm-agen)
       CGroup: /system.slice/amazon-ssm-agent.service
               ├─3355 /usr/bin/amazon-ssm-agent
               └─3382 /usr/bin/ssm-agent-worker
    
    Mar 29 02:53:54 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:54 INFO Agent will take identity f...EC2
    Mar 29 02:53:54 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:54 INFO [amazon-ssm-agent] using n...IPC
    Mar 29 02:53:55 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:54 INFO [amazon-ssm-agent] using n...IPC
    Mar 29 02:53:55 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:54 INFO [amazon-ssm-agent] using n...IPC
    Mar 29 02:53:55 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:54 INFO [amazon-ssm-agent] amazon-...0.0
    Mar 29 02:53:55 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:54 INFO [amazon-ssm-agent] OS: lin...d64
    Mar 29 02:53:55 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:54 INFO [CredentialRefresher] Iden...her
    Mar 29 02:53:55 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:55 INFO [amazon-ssm-agent] [LongRu...ess
    Mar 29 02:53:55 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:55 INFO [amazon-ssm-agent] [LongRu...ted
    Mar 29 02:53:55 ip-10-10-20-201.us-west-2.compute.internal amazon-ssm-agent[3355]: 2022-03-29 02:53:55 INFO [amazon-ssm-agent] [LongRu...nds
    Hint: Some lines were ellipsized, use -l to show in full.

    4. AWS Cli 에서 SSM 을 통한 EC2 접속

    외부 CT 에 AWSCli 를 설치 후 IAM API Key 권한을 설정한다.

    ## 접속할 Client의 IP 확인
    $ curl http://icanhazip.com
    1.2.3.4
    
    ## AWSCli 설치 
    (중요) SSM의 Session-Plugin 을 사용하기 위해서는 AWSCli 1.16 버전 이상이어야 한다.  
    $ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    unzip awscliv2.zip
    sudo ./aws/install
    
    ## Linux 용 SSM Session-Manager Plugin 설치
    $ curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm" -o "session-manager-plugin.rpm"
    $ rpm -Uvh session-manager-plugin.rpm
    $ session-manager-plugin
    The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
    
    ## 접근 정보 설정 
    본문 내용의 키는 임의 생성한 내용.
    $ aws configure
    AWS Access Key ID [None]: AKIAQ25632EPN7T7FFVT
    AWS Secret Access Key [None]: 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
    Default region name [None]: us-west-2
    Default output format [None]: json
    

    SSM 을 통한 실제 EC2 에 접근

    [root@node1 ~]# aws ssm start-session --target i-064f7ebc0bed75c74
    
    Starting session with SessionId: SSM-Only-0a9041d6b13f368ce
    sh-4.2$ bash
    [ssm-user@ip-10-10-20-201 bin]$ ifconfig
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
            inet 10.10.20.201  netmask 255.255.255.0  broadcast 10.10.20.255
            inet6 fe80::aa:14ff:fed7:abd  prefixlen 64  scopeid 0x20<link>
            ether 02:aa:14:d7:0a:bd  txqueuelen 1000  (Ethernet)
            RX packets 31846  bytes 8338621 (7.9 MiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 29180  bytes 6068149 (5.7 MiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            inet6 ::1  prefixlen 128  scopeid 0x10<host>
            loop  txqueuelen 1000  (Local Loopback)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    [ssm-user@ip-10-10-20-201 bin]$ 
    ※ 참고자료
    https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
    https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html
    https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/session-manager-getting-started.html
    



    암호화된 AMI 이미지를 AWS 계정간 공유하려면?

    CMK 공유 설정 없이, 암호화된 볼륨이 있는 프라이빗 AMI 를 AWS 계정간에 공유하면
    새 인스턴스 시작 시에 에러 메세지 없이 생성 후 그냥 인스턴스가 자동 종료(Terminated)되어 버립니다.

    키 또한 권한을 공유하여 사용해야 합니다.

    # 공유할 이미지를 지정해 주는 부분입니다.
    # 원본 AMI 계정에 IAM 관리형 정책을 만들고 IAM 에 할당합니다. 
     
    {
       "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "ec2:ModifyImageAttribute"
                ],
                "Resource": [
                    "arn:aws:ec2:us-west-2::image/<0e9fcdb7ae40e8f4c>"      
    ## 공유할 이미지의 리전 위치와 id ( ami-xxxxxxxxxxxxxxxxxx  에서 xxx부분입니다 ) 
                ]
            }
     ] 
    }
    # KMS 서비스에서 Key 를 공유 가능한 어카운트를 설정합니다. 
    # 원본 AMI 계정의 KMS 서비스에 가서 공유 할 AWS Account 넘버를 공유에 등록해 줍니다.
    
    
    # 공유 받은 쪽에서 복호화할 CMK 를 요청하는 부분입니다. 
    # 공유 받은 계정의 IAM 에 관리형 정책을 등록합니다.
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "kms:DescribeKey",
                    "kms:ReEncrypt*",
                    "kms:CreateGrant",
                    "kms:Decrypt"
                ],
                "Resource": [
                    "arn:aws:kms:us-west-2:891977874274:key/bc52517a-676b-4f1a-9d1a-d50241563abc" 
    ## 원본 AMI 의 KMS Key 권한을 요청하는 정책입니다. 
                ]                                                    
            }
        ]
    }
    
    

    이제 정상적으로 공유 받은 이미지에서 EC2 가 생성되고 정상 시작되는 것을 확인할 수 있습니다.

    참고 AWS Docs : https://aws.amazon.com/ko/blogs/security/how-to-share-encrypted-amis-across-accounts-to-launch-encrypted-ec2-instances/