빌드 날짜: 2026-08-29

참고자료

기타 업데이트

Amazon API Gateway

개요

용어

REST API vs HTTP API

둘 다 RESTful API 제품으로, REST API는 HTTP API보다 많은 기능을 지원하지만 대신 비용도 더 많이 든다

아래는 일부 발췌이며, 최신 사항 전체는 http-api-vs-rest 참고

공개 엔드포인트 유형

엔드포인트 유형REST APIHTTP API
엣지 최적화
리전
프라이빗

보안

보안 기능REST APIHTTP API
상호 TLS 인증
클라이언트 인증서 발급
AWS WAF

제한사항

링크. 아래는 일부 발췌

WebSocket 엔드포인트가 퍼블릭인 경우, 공격자가 새 연결 제한량의 상당량을 점유할 수 있는 문제가 있다

API리소스 또는 작업기본 할당량높일 수 있음
HTTP최대 통합 제한 시간30초아니요
WebSocket리전별 계정당 초당 새 연결 수500
WebSocket프레임 크기32KB아니요

자습서

REST API - Lambda 프록시 통합

Lambda 프록시 통합

교차 계정 Lambda 프록시 통합

다른 계정의 Lambda 함수로 요청 라우팅 가능 -- 단, 적절한 권한 설정 필요. AWS 콘솔에서 작업하는 경우 아래와 같이 권한 부여를 위한 AWS CLI 명령이 안내된다

↓ shell

aws lambda add-permission --function-name "arn:aws:lambda:{REGION}:{FUNCTION_OWNER_ACCOUNT_ID}:function:{TARGET_FUNCTION_NAME}" --source-arn "arn:aws:execute-api:{REGION}:{API_OWNER_ACCOUNT_ID}:{API_ID}/*/POST/path/*" --principal apigateway.amazonaws.com --statement-id {STATEMENT_ID} --action lambda:InvokeFunction # API_ID 예: abcdefg123 # STATEMENT_ID : 동일 정책 내에서 다른 statement와 구별되는 임의 문자열

Lambda 비 프록시 통합

Amazon AppFlow

두 SaaS 종단에 대하여 안전한 데이터 전송을 수행하도록 도와준다

예. Amazon S3에서 Google BigQuery로 데이터 적재

Amazon Athena

개요

Athena SQL

용어

시작하기

  1. Settings > 쿼리 결과를 저장할 S3 위치 지정
  2. 데이터베이스 생성

    ↓ sql

    create database logs
  3. 테이블 생성

    ↓ sql

    create external table service_name ( log_time bigint, event string, message string ) partitioned by ( hour string ) row format serde 'org.openx.data.jsonserde.JsonSerDe' with serdeproperties ('ignore.malformed.json' = 'true') location 's3://bucket/' tblproperties ( "projection.enabled" = "true", "projection.hour.type" = "date", "projection.hour.range" = "NOW-1YEARS,NOW", "projection.hour.format" = "yyyy/MM/dd/HH", "projection.hour.interval" = "1", "projection.hour.interval.unit" = "HOURS", "storage.location.template" = "s3://bucket/${hour}/" );
  4. 조회

    ↓ sql

    select * from service_name where hour = '2023/08/10/12' limit 100

Data source 연결

AWS Glue 이용

Athena Federated Query 이용

참고자료 : connectors-available

Databbase, table 생성

쿼리 결과로부터 테이블 생성

쿼리 실행하기

배열 다루기

배열의 모든 원소들은 하나의 공통 타입으로 표현할 수 있어야 한다

↓ 생성

select array [1, 2, 3] some_arr; select array [array [1, 2], array [3, 4]] some_arr;

↓ 접합

select array [1, 2] || array [3, 4] some_arr;

↓ 길이

select cardinality(array [1, 2, 3]) arr_len;

↓ 원소 참조

-- 인덱스는 1부터 시작 with tmp as ( select array [1, 2, 3] arr ) select arr[3] = element_at(arr, -1) from tmp;

↓ 원소 포함 여부

select contains(array [1, 2, 3], 2);

↓ 평탄화, 테이블화

select * from unnest(flatten(array [array [1, 2], array [3, 4]])) tmp(num);

↓ 배열 필터링

select filter(array [1, 2, 3], n -> n >= 2);

↓ 배열 정렬

select array_sort(array [1, 2, 3, 4], (x, y) -> y - x);

↓ 여러 행을 배열로 집계

select array_agg(num) arr from unnest(array [1, 2, 3, 4]) tmp(num);

↓ 배열 원소에 대한 집계

-- reduce(array, initialState, inputFunction, outputFunction) -- 아래는 의사코드 -- let result = initialState; -- for (let element of array) -- result = inputFunction(result, element) -- return outputFunction(result) select reduce(array [1, 2, 3, 4], 0, (result, num) -> result + num, (result) -> 'Result = ' || cast(result as varchar)); -- 하나의 문자열로 접합 select array_join(array [1, 2, 3], ', ');

JSON 다루기

↓ JSON 변환

-- JSON으로 변환 select cast(123 as json) json_number, cast('text' as json) json_string, cast(true as json) json_boolean, cast(null as json) json_null, cast(array [1, 2, 3] as json) json_arr, cast(map(array ['field1', 'field2'], array [1, 2]) as json) json_obj1, cast(cast(row(123, 'hello') as row(num int, txt varchar)) as json) json_obj2 -- JSON에서 변환 select cast(json '123' as int) f_int, cast(json '"text"' as varchar) f_varchar, cast(json 'true' as boolean) f_boolean, cast(json 'null' as int) f_null, cast(json '[1, 2, 3]' as array(int)) f_array, cast(json '{"field1":1,"field2":2}' as map(varchar, int)) f_map, cast(json '{"num":123,"txt":"hello"}' as row(num int, txt varchar)) f_struct

↓ JSON 속성 조회

select typeof(json_extract(json '{"num":123,"txt":"hello"}', '$.num')) = 'json', typeof(json_extract_scalar(json '123', '$')) = 'varchar', typeof(json_array_get(json '[1, 2, 3]', 0)) = 'json'

DDL

참고자료 : ddl-sql-reference

Amazon Aurora + RDS

주의/권장 사항

Database Insights 표시가 안 되는 경우, CLI로 확인

RDS 개요

엔진별 RDS 기능

블루/그린 배포

MariaDBMySQLOraclePostgreSQLSQL Server
OOXXX

프로덕션 데이터베이스 환경을 별도의 스테이징 환경에 복사하고, 지속적으로 동기화 수행. 프로덕션 환경에 영향을 주지 않으면서 스테이징 환경에서 데이터베이스를 변경한 다음, 최소 중단 시간으로 스테이징 환경을 프로덕션으로 승격 가능

교차 리전 자동 백업

MariaDBMySQLOraclePostgreSQLSQL Server
OOOOO

자동 백업으로 생성되는 스냅샷을 다른 리전에 복제하여 보관하도록 구성할 수 있다. 기존 인스턴스에 대해 설정하려면 RDS > Automated backups > 인스턴스 선택 > Actions > 교차 리전 복제 관리

리전 간 읽기 전용 복제본

MariaDBMySQLOraclePostgreSQLSQL Server
OOO

소스 DB 인스턴스와 다른 리전에 읽기 전용 복제본을 생성할 수 있다

데이터베이스 활동 스트림

MariaDBMySQLOraclePostgreSQLSQL Server
XXOXO

DB 인스턴스 감사 활동에 대한 경보를 설정하고 모니터링할 수 있다

듀얼 스택 모드

MariaDBMySQLOraclePostgreSQLSQL Server
OOOOO

IPv6도 이용할 수 있다

S3로 스냅샷 내보내기

MariaDBMySQLOraclePostgreSQLSQL Server
OOXOX

S3로 내보낸 스냅샷은 Amazon Athena 또는 Amazon Redshift Spectrum을 이용해 직접 분석할 수도 있다

IAM 데이터베이스 인증

MariaDBMySQLOraclePostgreSQLSQL Server
OOXOX

암호 대신 IAM 인증 토큰을 발급 받아 인증한다. 토큰 생성에 오버헤드가 발생하므로 초당 200개 이상의 새 인증이 필요한 경우엔 부적합할 수 있다

Kerberos 인증

MariaDBMySQLOraclePostgreSQLSQL Server
XOOOO

Kerberos 및 Microsoft Active Directory를 이용한 외부 인증 정보로 데이터베이스에 접속 가능

다중 AZ DB 클러스터

MariaDBMySQLOraclePostgreSQLSQL Server
XOXOX

성능 개선 도우미

MariaDBMySQLOraclePostgreSQLSQL Server
OOOOO

데이터베이스 성능을 분석하는 데 도움이 되는 자료를 수집하여 시각화한다

RDS Custom

MariaDBMySQLOraclePostgreSQLSQL Server
XXOXO

데이터베이스 환경 및 운영 체제에 액세스하여 커스터마이징 가능

RDS 프록시

MariaDBMySQLOraclePostgreSQLSQL Server
OOOOO

원본 데이터베이스에 대한 연결 풀을 제공한다. 애플리케이션 안에서 연결을 관리하지 않는 경우, 인스턴스에서 지원하는 것보다 많은 연결을 동시에 열어두려는 경우에 적합

Secrets Manager 통합

MariaDBMySQLOraclePostgreSQLSQL Server
OOOOO

RDS 마스터 암호를 Secrets Manager에 저장하고, 정기적으로 교체할 수 있다

RDS for PostgreSQL

논리적 복제

Aurora

파라미터 그룹 작업

DB 인스턴스 파라미터

DB 클러스터 파라미터

이벤트 알림

발생한 이벤트에 대하여 전송 순서를 보장하지 않음에 유의

이벤트 알림 구독

  1. 어떤 범주의 이벤트를 수신할 것인지 선택 : DB 클러스터, DB 인스턴스, 파라미터 그룹, ...
  2. 어떤 이벤트를 수신할 것인지 선택 : 생성, 삭제, 장애, 장애 조치, 점검, ...
  3. 구독 대상 선택
  4. 구독 생성

권한 부여

이벤트에서 트리거되는 규칙 생성

이벤트 범주 및 유형

USER_Events

App Runner

개요

코드 저장소 또는 컨테이너 이미지로부터 웹 앱을 구동한다

App Runner 배포를 위한 개발

Auto Scaling

크기 조정 계획

EC2 Auto Scaling

CDK, CloudFormation

CloudFormation이란?

시작하기

로컬 MySQL을 사용하는 단일 EC2 인스턴스로 WordPress 서비스 제공하는 샘플 템플릿을 통해 기본적인 사항을 알아본다원본 yaml

↓ yaml

AWSTemplateFormatVersion: '2010-09-09' Description: 'AWS CloudFormation Sample Template WordPress_Single_Instance: WordPress is web software you can use to create a beautiful website or blog. This template installs WordPress with a local MySQL database for storage. It demonstrates using the AWS CloudFormation bootstrap scripts to deploy WordPress. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.' Parameters: DBName: AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' ConstraintDescription: must begin with a letter and contain only alphanumeric characters. Default: wordpressdb Description: The WordPress database name MaxLength: '64' MinLength: '1' Type: String DBPassword: AllowedPattern: '[a-zA-Z0-9]*' ConstraintDescription: must contain only alphanumeric characters. Description: The WordPress database admin account password MaxLength: '41' MinLength: '8' NoEcho: 'true' Type: String DBRootPassword: AllowedPattern: '[a-zA-Z0-9]*' ConstraintDescription: must contain only alphanumeric characters. Description: MySQL root password MaxLength: '41' MinLength: '8' NoEcho: 'true' Type: String DBUser: AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' ConstraintDescription: must begin with a letter and contain only alphanumeric characters. Description: The WordPress database admin account username MaxLength: '16' MinLength: '1' NoEcho: 'true' Type: String InstanceType: AllowedValues: - t2.micro - t2.small ConstraintDescription: must be a valid EC2 instance type. Default: t2.small Description: WebServer EC2 instance type Type: String KeyName: ConstraintDescription: must be the name of an existing EC2 KeyPair. Description: Name of an existing EC2 KeyPair to enable SSH access to the instances Type: AWS::EC2::KeyPair::KeyName SSHLocation: AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Default: 0.0.0.0/0 Description: The IP address range that can be used to SSH to the EC2 instances MaxLength: '18' MinLength: '9' Type: String Mappings: AWSInstanceType2Arch: t2.micro: Arch: HVM64 t2.small: Arch: HVM64 AWSRegionArch2AMI: us-east-1: HVM64: ami-60b6c60a HVMG2: ami-e998ea83 PV64: ami-5fb8c835 us-west-1: HVM64: ami-d5ea86b5 HVMG2: ami-943956f4 PV64: ami-56ea8636 Resources: WebServer: Type: AWS::EC2::Instance CreationPolicy: ResourceSignal: Timeout: PT15M Metadata: AWS::CloudFormation::Init: configSets: wordpress_install: - install_cfn - install_wordpress - configure_wordpress configure_wordpress: commands: 01_set_mysql_root_password: command: !Sub | mysqladmin -u root password '${DBRootPassword}' test: !Sub | $(mysql ${DBName} -u root --password='${DBRootPassword}' >/dev/null 2>&1 </dev/null); (( $? != 0 )) 02_create_database: command: !Sub | mysql -u root --password='${DBRootPassword}' < /tmp/setup.mysql test: !Sub | $(mysql ${DBName} -u root --password='${DBRootPassword}' >/dev/null 2>&1 </dev/null); (( $? !=0)) 03_configure_wordpress: command: /tmp/create-wp-config cwd: /var/www/html/wordpress install_cfn: files: /etc/cfn/cfn-hup.conf: content: !Sub | [main] stack= ${AWS::StackId} region=${AWS::Region} group: root mode: '000400' owner: root /etc/cfn/hooks.d/cfn-auto-reloader.conf: content: !Sub | [cfn-auto-reloader-hook] triggers=post.update path=Resources.WebServer.Metadata.AWS::CloudFormation::Init action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServer --configsets wordpress_install --url https://stackbuilder.amazonaws.com group: root mode: '000400' owner: root services: sysvinit: cfn-hup: enabled: true ensureRunning: true files: - /etc/cfn/cfn-hup.conf - /etc/cfn/hooks.d/cfn-auto-reloader.conf install_wordpress: files: /tmp/create-wp-config: content: !Sub | #!/bin/bash -xe cp /var/www/html/wordpress/wp-config-sample.php /var/www/html/wordpress/wp-config.php sed -i "s/'database_name_here'/'${DBName}'/g" wp-config.php sed -i "s/'username_here'/'${DBUser}'/g" wp-config.php sed -i "s/'password_here'/'${DBPassword}'/g" wp-config.php group: root mode: '000500' owner: root /tmp/setup.mysql: content: !Sub | CREATE DATABASE ${DBName}; CREATE USER '${DBUser}'@'localhost' IDENTIFIED BY '${DBPassword}'; GRANT ALL ON ${DBName}.* TO '${DBUser}'@'localhost'; FLUSH PRIVILEGES; group: root mode: '000400' owner: root packages: yum: httpd: [] mysql: [] mysql-devel: [] mysql-libs: [] mysql-server: [] php: [] php-mysql: [] services: sysvinit: httpd: enabled: true ensureRunning: true mysqld: enabled: true ensureRunning: true sources: /var/www/html: http://wordpress.org/latest.tar.gz Properties: ImageId: !FindInMap [AWSRegionArch2AMI, !Ref 'AWS::Region', !FindInMap [AWSInstanceType2Arch, !Ref InstanceType, Arch]] InstanceType: Ref: InstanceType KeyName: Ref: KeyName SecurityGroups: - Ref: WebServerSecurityGroup UserData: Fn::Base64: !Sub | #!/bin/bash -xe yum update -y aws-cfn-bootstrap /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource WebServer --configsets wordpress_install --region ${AWS::Region} /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource WebServer --region ${AWS::Region} WebServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "Enable HTTP access via port 80 locked down to the load balancer + SSH access" SecurityGroupIngress: - CidrIp: 0.0.0.0/0 FromPort: '80' IpProtocol: tcp ToPort: '80' - CidrIp: !Ref SSHLocation FromPort: '22' IpProtocol: tcp ToPort: '22' Outputs: PublicIP: Description: EC2 public IP Value: !GetAtt WebServer.PublicIp WebsiteURL: Description: WordPress Website Value: !Sub "http://${WebServer.PublicDnsName}/wordpress"
  1. 샘플은 6개의 최상위 섹션을 갖지만(AWSTemplateFormatVersion, Description, Parameters, Mappings, Resources, Outputs), 이 중 Resources 섹셕만 필수 요소다
  2. Resources.WebServer : 템프릿 내에서 리소스 참조에 사용하는 논리적 이름
  3. Parameters : 템플릿에서 사용할 변수 정의

    Ref 함수로 parameter와 resource 접근

    • Resources.WebServer.Properties.KeyName = { Ref: "KeyName" }
    • Resources.WebServer.Properties.SecurityGroups[0] = { Ref: "WebServerSecurityGroup" }
  4. Outputs 섹션은 스택 생성 후 출력 탭에서 확인할 수 있는 값을 정의한다

샘플 템플릿

CDK(Cloud Development Kit)

고급 프로그래밍 언어를 이용해 인프라 작성 > CloudFormation 템플릿 자동 생성 > 스택 배포

예시 :hello_world

  1. CDK 설치 :cli

    ↓ shell

    npm install -g aws-cdk
  2. 앱 생성(JavaScript)

    ↓ shell

    mkdir hello-cdk cd hello-cdk cdk init app --language javascript
  3. ^ 정상인지 확인

    ↓ shell

    cdk ls

    HelloCdkStack가 결과에 포함되어야 한다

  4. 서비스 구성요소 추가

    ↓ lib/hello-cdk-stack.js

    const cdk = require('aws-cdk-lib'); const s3 = require('aws-cdk-lib/aws-s3'); class HelloCdkStack extends cdk.Stack { constructor(scope, id, props) { super(scope, id, props); new s3.Bucket( this, // Scope 'MyFirstBucket', // Id { // Properties versioned: true } ); } }
    = { HelloCdkStack }
  5. CloudFormation 템플릿 생성

    ↓ shell

    cdk synth

    YAML 포맷의 템플릿이 출력되며, cdk.out 디렉터리에 JSON 포맷 템플릿도 작성된다

  6. 스택 배포

    ↓ shell

    cdk deploy
  7. 스택 정의 업데이트 -- 스택 삭제 시 모든 객체와 버킷을 삭제하도록

    ↓ lib/hello-cdk-stack.js

    new s3.Bucket( this, // Scope 'MyFirstBucket', // Id { // Properties versioned: true, removalPolicy: cdk.RemovalPolicy.DESTROY, autoDeleteObjects: true } );
  8. 변경 사항 확인

    ↓ shell

    cdk diff
    • 객체 자동 삭제를 위해 Lambda 함수가 추가되는 것을 볼 수 있다
    • 추가적으로 cdk synth의 결과를 비교해보는 것도 유용할 수 있다
  9. 스택 업데이트 배포

    ↓ shell

    cdk deploy
  10. 스택 제거

    ↓ shell

    cdk destroy

EC2

개요

AMI

AMI 유형

시작 권한

공유 AMI 사용 시 보안 유의

액세스 권한을 상실하는 사고를 방지하기 위해 두 개의 SSH 세션을 시작하고, 하나는 작업이 끝날 때까지 계속 유지

루트 디바이스 스토리지

특성EBS 지원 AMI인스턴스 스토어 지원 AMI
부팅 시간보통 1분 이하보통 5분 이하
루트 디바이스 크기 제한64TiB10GiB
데이터 지속성인스턴스를 종료해도 루트 볼륨이 지속되도록 설정 가능 -- 기본값은 삭제항상 인스턴스 수명 주기 동안만 유지
중지 상태인스턴스는 중지 상태일 수 있으며, 루트 볼륨은 EBS에 계속 유지인스턴스는 중지 상태일 수 없음

가상화

AMI 수명 주기

AMI 복사

AMI 저장 및 복원

S3로 AMI 저장 및 S3로부터 AMI 복원 가능

Amazon Linux

개요

Amazon Linux 2022

aws configure

인스턴스 내에서 aws cli 명령을 실행하려는 경우, AMI에 미리 자격 증명을 설정하는 것이 편리하다

CodeDeploy agent 설치

↓ shell

$ sudo yum install ruby -y $ sudo yum install wget -y # 리전에 따라 아래 url은 달라짐 $ wget https://aws-codedeploy-ap-northeast-2.s3.amazonaws.com/latest/install $ chmod +x ./install $ sudo ./install auto $ sudo service codedeploy-agent status

JDK(Amazon Corretto) 설치

↓ shell

$ sudo rpm --import https://yum.corretto.aws/corretto.key $ sudo curl -L -o /etc/yum.repos.d/corretto.repo https://yum.corretto.aws/corretto.repo $ sudo yum install -y java-17-amazon-corretto-devel

인스턴스 유형

인스턴스 유형 이름 규칙

인스턴스 유형 이름 ::= 인스턴스 패밀리 || 세대 || 추가 기능(들)

추가 기능
aAMD 프로세서
gAWS Graviton 프로세서
i인텔 프로세서
d인스턴스 스토어
n네트워크 최적화
e추가 스토리지 또는 메모리
z높은 클록

범용

컴퓨팅 최적화

메모리 최적화

스토리지 최적화

가속 컴퓨팅

인스턴스 구입 옵션

온디맨드 인스턴스

예약 인스턴스

스팟 인스턴스

인스턴스 구성

사용자 관리

인스턴스를 여러 사용자가 공유하고, 사용자 별로 별도 작업공간을 가져야 하는 경우, 기본 사용자(ec2-user, ...)를 공유하는 것보다 신규 사용자를 생성하는 것이 보안상 안전하다

시작 시 명령 실행

사용자 데이터 및 shell 스크립트

예. 인스턴스 시작 시 CodeDeploy 실행

↓ 사용자 데이터

#!/bin/bash aws deploy create-deployment --application-name AppName --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name GroupName --s3-location bucket=BucketName,bundleType=zip,key=ObjectKey

사용자 데이터 및 cloud-init

인스턴스 메타데이터 서비스

IMDSv2 사용

IMDSv1은 일회성 요청/응답을 교환하는데, IMDSv2는 이에 토큰 헤더를 추가하여 SSRF 공격을 상당 부분 방지한다. 현재 IMDSv2 사용은 선택사항.

사용 제한

네트워킹

리전 및 영역

리전

가용 영역

Local Zone

Wavelength Zone

AWS Outposts

AWS에서 설계한 하드웨어로 제작된, 구성 가능한 완전관리형 컴퓨팅 및 스토리지 랙을 임의 데이터 센터, 코로케이션, 온프레미스 시설에서 사용

인스턴스 IP 주소 지정

프라이빗 IPv4 주소

프라이빗 IPv4 주소는 동일 VPC 내에서 인스턴스 간 통신에 사용될 수 있다. IPv4 주소 지정 프로토콜은 비활성화할 수 없다. 점유한 프라이빗 IPv4 주소는 인스턴스 종료 시 반환된다

퍼블릭 IPv4 주소

탄력적 IP 주소(EIP: Elastic IP)

IPv6 주소

탄력적 네트워크 인터페이스(ENI)

네트워크 대역폭

인스턴스에서 사용 가능한 네트워크 대역폭은 실제 최대 대역폭과 다르다

배치 그룹

새 인스턴스를 시작하면 기본적으로 기존 인스턴스들과 하드웨어를 적게 공유하도록 분산된다. 배치 그룹을 이용하여 이 동작을 재정의할 수 있다

제한사항

보안

보안 그룹

스토리지

EBS

EBS 다중 연결

Amazon Data Lifecycle Manager

탄력적 볼륨

사용 중인 볼륨의 크기를 늘리거나 유형을 변경할 수 있다. 인스턴스를 재시작할 필요는 없지만, 크기를 변경한 경우 파일 시스템을 확장해야 한다

I/O 특성

인스턴스 스토어

Elastic Beanstalk

개요

개념

Elastic Beanstalk 생성 시 만들어지는 리소스 목록

고급 설정

ALB에 부여할 보안 그룹 지정

↓ 예. alb.config

option_settings: aws:elbv2:loadbalancer: ManagedSecurityGroup: "sg-xxx" SecurityGroups: "sg-xxx"

SSH를 public으로 공개하는 기본 보안 그룹이 생성되는 문제

IAM; Identity and Access Management

AWS 계정

AWS Organizations

IAM이란?

IAM 작동 방식

Terms

Request

보안 주체가 AWS Management Console, AWS API, AWS CLI를 사용해 전송하는 요청에는 다음의 정보가 포함된다 -- 요청 컨텍스트

Authorization

AWS는 요청 컨텍스트에 적용되는 각 정책을 확인하여, 하나라도 거부되는 경우 전체 요청을 거부하고 평가를 중지한다. 아래는 요청 평가에 대한 일반 규칙

  1. 기본적으로 모든 요청은 거부
  2. 정책에 포함된 명시적 허용은 위 거부를 재정의
  3. 권한 경계 또는 세션 정책이 있는 경우 위 허용을 재정의
  4. 정책의 명시적 거부는 위 허용을 무시

ABAC란?

IAM 시작하기 > IAM 관리자 및 사용자 그룹 생성

  1. 루트 사용자로 로그인
  2. 탐색 표시줄 > 내 계정 > 결제 정보에 대한 IAM 사용자 및 역할 액세스 편집 > IAM 액세스 활성

    관리자 사용자가 비용 및 사용량과 상호작용하려면 위 작업 필요

  3. IAM 콘솔에서 관리자 사용자 추가. 여러 명인 경우 사용자 그룹도 추가
  4. 사용자 또는 사용자 그룹에 AdministratorAccess 정책 연결

자습서

역할을 사용하여 AWS 계정 간 권한 위임

  1. 리소스를 가진 계정(A)에서 리소스 액세스 역할 생성

    역할 생성 시, 신뢰할 수 있는 엔터티 유형으로 "다른 AWS 계정" 지정

  2. 권한을 위임받고자 하는 계정(B)에서 적절한 IAM 보안 주체에 AssumeRole 허용 정책 연결

    ↓ 인라인 정책 예

    { "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::ACCOUNT-A-ID:role/ROLE-NAME" } }
  3. 역할 전환 테스트
    • AWS 콘솔
      • 역할 전환 시 ExternalId를 요구하지 않아야만 가능
      • 방법 1 : 역할 생성 시 Role Summary 페이지에서 제공된 url 사용
      • 방법 2 : 탐색 표시줄 > Switch Role > 계정 ID 또는 alias, 역할 이름 수동 입력
    • AWS CLI

      ↓ aws-cli

      aws sts assume-role --role-arn "ROLE-ARN" --role-session-name "ARBITRARY-SESSION-NAME" # 환경 변수로 세션 키 설정 export AWS_ACCESS_KEY_ID="GIVEN-BY-ASSUME-ROLE" export AWS_SECRET_ACCESS_KEY="GIVEN-BY-ASSUME-ROLE" export AWS_SESSION_TOKEN="GIVEN-BY-ASSUME-ROLE"
    • AWS API

      AssumeRole 호출 응답으로 주어진 임시 자격 증명을 사용하여 API 호출

ABAC 사용

ID

Roles

역할을 사용할 수 있는 주체

EC2 애플리케이션에서 역할 사용

EC2 인스턴스에 IAM 역할을 할당하면 장기 자격 증명을 인스턴스에 배포하지 않아도 된다. 예를 들어, AWS Java SDK에서 인증 정보 없이 서비스 클라이언트 인스턴스 생성 시 DefaultAWSCredentialsProviderChain에 정의된 순서대로 인증 정보를 조회한다

  1. 환경 변수 : AWS_ACCESS_KEY, AWS_SECRET_KEY

    Java SDK 외의 경우엔 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

  2. Java System Properties : aws.accessKeyId, aws.secretKey
  3. Web Identity Token credential
  4. Credential profile : ~/.aws/credentials
  5. Amazon EC2 container service로 전달되는 인증 정보
  6. Amazon EC2 metadata service로 전달되는 인증 정보

인스턴스 내부에서 aws cli를 직접 실행하는 경우엔 얘기가 다르다. profile을 추가로 지정해야 하고, 해당 profile로 assume role할 수 있는 권한이 있어야 한다

CloudTrail을 사용하여 이벤트 로깅

CloudTrail 이벤트

액세스 관리

정책 및 권한

정책 유형

JSON 정책 언어 문법(2012-10-17)

↓ text

policy = { <version_block?> <id_block?> <statement_block> } <version_block> = "Version" : ("2008-10-17" | "2012-10-17") <id_block> = "Id" : <policy_id_string> <statement_block> = "Statement" : [ <statement>, <statement>, ... ] <statement> = { <sid_block?>, <principal_block?>, <effect_block>, <action_block>, <resource_block>, <condition_block?> } <sid_block> = "Sid" : <sid_string> <effect_block> = "Effect" : ("Allow" | "Deny") <principal_block> = ("Principal" | "NotPrincipal") : ("*" | <principal_map>) <principal_map> = { <principal_map_entry>, <principal_map_entry>, ... } <principal_map_entry> = ("AWS" | "Federated" | "Service" | "CanonicalUser") : [<principal_id_string>, <principal_id_string>, ...] <action_block> = ("Action" | "NotAction") : ("*" | [<action_string>, <action_string>, ...]) <resource_block> = ("Resource" | "NotResource") : ("*" | [<resource_string>, <resource_string>, ...]) <condition_block> = "Condition" : { <condition_map> } <condition_map> = { <condition_type_string> : { <condition_key_string> : <condition_value_list> }, <condition_type_string> : { <condition_key_string> : <condition_value_list> }, ... } <condition_value_list> = [<condition_value>, <condition_value>, ...] <condition_value> = ("string" | "number" | "Boolean")

정책 조건 연산

정책 예제

참고 자료 : access_policies_examples

액세스 분석기

IAM Access Analyzer는 외부 엔터티와 공유되는 조직 및 계정 내 리소스를 식별하여 액세스가 의도한 액세스인지, 의도하지 않은 보안 위험인지 확인할 수 있다. 모든 상용 AWS 리전에서 무료로 IAM 콘솔 및 API를 통해 이용 가능

Lambda

개요

Lambda는 상시 가동 중인 서버 없이, 요청/이벤트가 있을 때만 코드를 실행하는 컴퓨팅 서비스. 이러한 특성상 수평적 확장이 상당히 용이하다(초당 수천 개 요청까지 처리 가능)

프로그래밍 모델

VPC 네트워킹

동시성 제어

비동기 호출

이벤트 소스 매핑

함수 URL

권한

런타임

실행 환경

Lambda 실행 환경
<Lambda 실행 환경>[원본 보기]
Lambda 실행 환경 수명 주기
<Lambda 실행 환경 수명 주기>[원본 보기]

Lambda@Edge

가능한 실행 지점

  1. Viewer Request : CloudFront가 요청을 받아, 캐시를 검사하는 시점에 실행
  2. Origin Request : 캐시에 항목이 없어 원본(origin)을 요청하는 시점에 실행
  3. Origin Response : 원본(origin) 응답을 받은 이후, 캐시에 적재하기 전에 실행
  4. Viewer Response : 응답을 엔드 유저에게 전달하기 전에 실행

Proton

개요

컨테이너 기반 서버리스 애플리케이션에 대한 2가지 자동화를 제공한다. 템플릿 생성, 게시, 관리에는 비용이 청구되지 않는다

  1. 플랫폼 관리자가 정의한 IaC(infrastructure as code) 템플릿대로 인프라를 자동 구축

    플랫폼 관리자는 버전 관리되는 환경 및 서비스 템플릿을 정의한다. 환경 템플릿은 서비스들이 공유하는 인프라 집합을 정의하고, 서비스 템플릿은 각 서비스가 필요로 하는 인프라 요소들을 정의한다

  2. 통합된 CI/CD 기능을 통해 코드 자동 배포

시작하기

Proton service diagram
<Proton service diagram>[원본 보기]
  1. 환경 템플릿 생성 ~ 배포
    • 템플릿에 필요한인자들을 식별 후스키마 파일로 작성
    • IaC 파일 작성
      • AWS 관리형으로 만드는 경우 : CloudFormation 템플릿 파일에,Jinja를 이용해 변수 사용
      • 고객 관리형으로 만드는 경우 :Terraform템플릿 파일
    • 스키마 + IaC + 매니페스트 파일들을 번들링
    • 템플릿 번들을 참조하여 템플릿 생성(또는 업데이트) 후 템플릿 게시 및 배포
  2. 배포한 특정 버전의 환경 템플릿에 인자를 지정하여 환경 생성
  3. 서비스 템플릿 생성 ~ 배포
  4. 서비스 생성에 사용할 코드 저장소 - 브랜치 작성
  5. 배포한 특정 버전의 서비스 템플릿에 인자와 코드 저장소 및 브랜치를 지정하여 서비스 및 서비스 인스턴스 생성
  6. 최종적으로 개발자가 지정한 환경에 지정한 수량만큼의 서비스 인스턴스가 생성된다

WAF, Firewall Manager, Shield

개요

WAF

Rule

Rule action

Rule type

Rule statement

↓ Rule 예시

{ "Name": "RequestRate-by-IP", "Priority": 0, "Statement": { "RateBasedStatement": { "Limit": 1500, "AggregateKeyType": "IP" } }, "Action": { "Block": {} }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "RequestRate-by-IP" } }

기타 서비스

S3

API 호출 빈도 제한사항

2024-05-13 변경사항

AWS 계정 또는 조직 외부에서 발생한 요청에 대해 HTTP 403 응답을 반환하는 요청에 대해서는 요청 및 대역폭 요금이 발생하지 않게 됨

VPC

Client VPN

개요

VPC를 외부에 개방하지 않으면서 인증된 클라이언트와의 네트워킹을 허용하는 클라이언트 기반 VPN 서비스

인증서 관리

클라이언트 인가

연결 핸들러

분할 터널

PrivateLink

퍼블릭 인터넷을 통해 트래픽을 보내지 않고 VPC에서 AWS API를 호출

    security-diagram.png
    <security-diagram.png>[원본 보기]
  1. AWS 계정 생성시 VPC, 서브넷, 라우팅 테이블, 인터넷 게이트웨이, 네트워크 ACL 등은 가용 리전 및 AZ에 대해 기본적으로 생성된다

    NAT 게이트웨이 등 사용자가 필요에 의해 직접 추가하는 리소스들은 추가 요금이 발생함에 유의

  2. VPC; Virtual Private Cloud

    AWS 계정 및 AWS 리전에 대해 고유한 전용 네트워크

  3. AZ; Availability Zone, 가용 영역

    AWS 리전은 2개 이상의 가용 영역으로 구성되며, 각 AZ는 서로의 장애로부터 물리적으로 격리된다

  4. Subnet
    • VPC 내 할당 가능한 IP 주소 영역의 일부. AZ 안에 서브넷을 작성할 수 있으며, 다른 AZ와 공유되지 않는다
    • Private subnet 안에서 생성된 인스턴스에는 public IP가 부여되지 않는다

    또는 인스턴스 실행 시 public IP 부여 여부를 결정할 수 있으며, 인터넷 게이트웨이와 연결되지 않은 라우팅 테이블에 서브넷을 연결하면 결과적으로 public IP가 없는 것과 같은 효과를 갖는다

  5. Route table

    VPC 내부↔외부 네트워크 트래픽을 제어하는 규칙 정의. 라우팅 테이블 : 서브넷 = 1 : N 관계

  6. Internet gateway
    • VPC 내부와 외부 인터넷 사이의 연결 통로
    • VPC 내 인스턴스 → 외부 인터넷 : 트래픽의 송신 주소를 인스턴스의 public IP/Elastic IP로 설정
    • 외부 인터넷 → VPC 내 인스턴스 : 트래픽의 수신 주소를 인스턴스의 private IP로 설정
  7. NAT gateway
    • private 서브넷 내의 인스턴스가 외부 인터넷과 연결을 맺을 수 있도록 해준다

      외부 인터넷이 먼저 연결을 시작할 수는 없다

    • VPC 내 인스턴스 → 외부 인터넷 : 트래픽의 송신 주소를 NAT의 Elastic IP로 설정
    • 외부 인터넷 → VPC 내 인스턴스 : 트래픽의 수신 주소를 인스턴스의 private IP로 설정
  8. VPC endpoint

    인터넷 게이트웨이를 거치지 않고, VPC 내 인스턴스와 AWS 서비스 또는 엔드포인트 서비스 사이의 직접적인 연결 지원

  9. NIC; Network Interface Controller

    서브넷 내에서, 특정 보안 그룹 집합을 갖는 NIC를 생성할 수 있다. 인스턴스 : NIC = 1 : N 관계이며, 결과적으로 인스턴스는 N개의 private IP 주소를 할당받는다

  10. Network ACL; Network Access Control List

    서브넷(들)에 대한 선택적인 방화벽 계층

    보안 그룹과 네트워크 ACL 비교
    Security groupNetwork ACL
    인스턴스 단위 동작서브넷 단위 동작
    허가 규칙만 존재허가 + 거부 규칙 존재
    Is stateful: 응답은 무조건 허가Is stateless: 응답도 규칙에 의해 허가되어야 한다
    규칙은 순서 없이 모두 평가규칙은 우선순위에 의해 순차적으로 평가
    적용된 인스턴스에 한해 적용서브넷에 포함된 모든 인스턴스에 자동 적용(따라서 선택적인 보안 계층을 제공함을 의미)
  11. VPC peering connection

    두 VPC(서로 다른 AWS 계정이어도 됨) 사이의 연결 지원. 인터넷 게이트웨이, VPN을 거치지 않고 각자의 private IP를 이용하여 AWS backbone을 통해 다이렉트로 암호화된 통신 가능

  12. Client VPN

    OpenVPN을 이용한 사용자 PC와 VPC 사이의 VPN 지원. private IP 주소를 이용한 인스턴스 접근이 가능해진다

  13. Site-to-Site VPN

    VPC와 사용자 네트워크 사이의 VPN 터널 유지

  14. Traffic Mirroring

    두 EC2 인스턴스 사이의 트래픽을 미러링할 수 있다. ALB도 AWS 관리 EC2 인스턴스이므로, EC2 - ALB 사이의 트래픽도 확인할 수 있다.참고 자료

CloudFront

캐시 정책 TTL 관련

로드 밸런서를 원본으로 사용하는 경우 고려사항