AWS, GCP, Azure 등의 퍼블릭 클라우드를 사용하다보면 마주하게 되는 꼭 난감한 상황이 있습니다.
내가 어떤 클라우드 리소스를 생성했는지, 어디에 어떤 리소스를 추가했는지 파악하지 못하는 경우가 있다는 것입니다.
특히 관리해야 하는 퍼블릭 클라우드 리소스의 규모가 크고 방대할수록 이 문제는 심화되는데, 퍼블릭 클라우드는 리소스의 사용량만큼 비용을 지불해야 하는 구조이기 때문에 이는 재정적으로 큰 문제로 다가올 수 밖에 없습니다.
이같은 문제는 보통 내가 관리하는 퍼블릭 클라우드 리소스의 Observability, 즉 관측가능성을 확보하지 못할 때 발생하게 됩니다.
즉 관측가능성이 어플리케이션이나 인프라에서 말하는 메트릭, 로그, 트레이스 뿐만 아니라 클라우드 리소스에도 통용될 수 있다는 말입니다.
그리고 이런 클라우드 리소스의 관측가능성을 확보할 수 있도록 등장한 OSS가 바로 Steampipe입니다.
Steampipe는 "select * from cloud;"를 모토로 하여 쿼리 형식으로 클라우드 리소스 현황을 분석할 수 있는 도구입니다.
이번 포스팅에서는 Steampipe를 어떻게 활용할 수 있는 지, 그리고 제가 만든 Steampipe 기반의 프로젝트인 GCP IAM(Identity & Access Management) Report를 이용하는 법까지 알아보겠습니다.
1. Steampipe란?
Steampipe는 SQL 기반의 클라우드 리소스 분석을 지원하는 OSS 툴입니다.
AWS,Azure,GCP와 같은 대중적인 퍼블릭 클라우드부터 IBM,Alibaba와 같은 퍼블릭 클라우드도 지원하며, Slack, Github, 심지어 Kubernetes같은 비 퍼블릭 클라우드 리소스도 SQL로 분석이 가능합니다.
흔히 사용하는 SQL문을 지원하며(더 정확히는 Postgresql 기반의 SQL) 별다른 DB를 설치하지 않아도 되기 때문에 사용이 간편하고 빠릅니다.
특히 리소스 사용이 곧 과금인 퍼블릭 클라우드 리소스 현황을 파악하기에 좋은 도구라고 생각합니다.
내부 아키텍쳐는 Postgresql Extension인 Postgres Foreign Data Wrapper를 사용해서 API call이나 provider 제공 코드를 이용하여 돌아온 값을 기반으로 Postgresql 테이블을 짜는 구조로 되어있습니다.
위 아키텍쳐에서 볼 수 있듯이 FDW가 gRPC 포맷의 메세지를 전송하기 때문에 속도도 빠를 뿐더러 API call 및 Code 부분은 캡슐화되어있기 때문에 Steampipe를 사용할때 이 로직을 전혀 신경 쓸 필요가 없게 되어있습니다.
덕분에 Plugin만 구현하면 이를 이용해서 Postgresql 기반의 쿼리문으로 이용할 수 있는 구조입니다.
기본적으로 사용하고자 하는 Plugin을 설치하고 DML 문을 이용하여 원하는 리소스를 select하는 과정으로 사용할 수 있습니다.
예를 들어 GCP의 compute instance 목록을 조회하고자 한다면 GCP Plugin을 설치한 뒤 "select * from gcp_compute_instance" 쿼리문을 입력하면 됩니다.
이는 GCP plugin에서 이미 Compute instance에 대한 목록을 조회하는 API call을 구현해놨으며 이를 Postgresql 테이블로 캡슐화해놨기 때문에 일반 테이블을 조회하듯이 사용이 가능한 것입니다.
2. Steampipe 기본 사용법
2-1. 아래 명령어와 같이 입력해 원하는 steampipe plugin을 설치합니다.
ex) aws plugin 설치
1
|
steampipe plugin install aws
|
cs |
2-2. 실행환경에 설치한 Plugin의 crendential로 인증할 수 있는 수단을 제공합니다.(CLI, Env variable, key 등...)
ex) GCP CLI를 이용한 Credential 제공
2-3. 아래 명령어를 입력해 원하는 Interactive query session을 엽니다.
1
|
steampipe query
|
cs |
인터렉티브 쿼리 세션을 여는 것으로 쿼리문을 인터렉티브하게 입력해 리소스 테이블을 조회할 수 있습니다. 여기서 DML문을 입력해 원하는 리소스를 조회할 수 있습니다.
2-4. 쿼리문을 입력해 원하는 리소스를 조회합니다.
ex)
- GCP 프로젝트에 존재하는 모든 Compute image의 모든 정보를 조회
- AWS 계정에 존재하는 모든 S3 버켓의 모든 정보를 조회
- AWS IAM User 중 name이 root인 리소스의 모든 정보를 조회
- GCP 프로젝트에 존재하는 bigquery 테이블 중 last_modified_time 값이 2021년 12월 5일 이후인 것의 table id, dataset id, last modified time을 조회
3. Steampipe 모드
지금까지와 같이 steampipe를 이용하는 간단한 방법을 알아봤습니다. 이런 인터렉티브 세션 말고도 다양한 방법으로 steampipe를 이용할 수 있습니다.
그 중에 한 번에 여러 쿼리문을 실행하는 간편한 방법으로 Steampipe 모드를 사용할 수 있습니다.
Steampipe 모드는 steampipe hub에 등록되어 있거나 자체 제작한 모드를 기반으로 일종의 벤치마크를 수행할 수 있도록 쿼리들을 묶어준 개념입니다.
Steampipe 모드를 이용해 간편하게 쿼리 묶음을 한 번에 실행하거나 이를 실행할 수 있는 나만의 모드를 제작할 수 있습니다.
예를 들어 현재 Steampipe에서 제공하는 공식 모드 중 하나인 "AWS compliance" 모드를 사용해보겠습니다.
우선 아래 명령어로 AWS compliance 모드가 담긴 레포지토리를 가져옵니다.
1
|
git clone https://github.com/turbot/steampipe-mod-aws-compliance.git
|
cs |
가져온 레포지토리 폴더로 이동한 뒤 아래 명령어로 모드를 실행합니다.
1
|
steampipe check all
|
cs |
이후 모드에 포함된 쿼리들이 실행되고, 그 후 쿼리가 실행된 결과를 벤치마크 형식으로 볼 수 있습니다.
이렇게 AWS compliance를 준수했는지 확인할 수 있는 쿼리들을 한 번에 실행한 후, 준수 결과를 확인할 수 있습니다.
현재 Steampipe에서 제공되는 모드들은 cis, nist, pci 등의 컴플라이언스를 준수했는지 확인할 수 있는 벤치마크와 더불어,
사용되고 있지 않는 리소스를 확인하는 등 요금 절약을 위한 Thrifty 벤치마크, 태그 기준을 잘 준수했는지 확인하는 Tag 벤치마크 등을 제공하고 있습니다.
4. Steampipe 모드 제작
앞서 보았듯이 Steampipe 모드는 여러 쿼리를 한 번에 실행해 벤치마크 형식으로 결과를 볼 수 있는 편리한 개념입니다.
이미 제작된 모드를 편리하게 사용할 수도 있지만, 아이디어만 있다면 내가 직접 모드를 제작해 사용할 수도 있습니다.
이번 장에서는 제가 제작한 GCP IAM Best practic를 준수했는지 확인할 수 있는 벤치마크 GCP IAM(Identity & Access Management) Report 모드를 제작하는 과정을 통해 어떻게 Steampipe 모드를 제작하고 사용할 수 있는지 알아봅니다.
4-1. 우선 모드를 통해 실행하고자 하는 쿼리문을 작성합니다.
제작하고자 하는 모드가 GCP IAM의 Best-practice를 준수했는지 확인하는 벤치마크이므로 이에 대한 쿼리문을 작성해야 합니다.
우선 GCP IAM 사용에 대한 Best-practice 정보를 확인해야 합니다. 아래 GCP 공식 document에서 GCP IAM 사용 시 지켜야 할 Best-practice 리스트를 제공하고 있습니다.
https://cloud.google.com/iam/docs/using-iam-securely
이제 도큐먼트에서 명시한 여러 Best-pracice 리스트 중 Steampipe를 통해 자동화할 수 있는 개체를 선별합니다.
예를 들어 "Basic role을 가급적이면 사용하지 않아야 한다"는 개체는 GCP User 중 Basic role이 부여되어 있는 user가 있을 시 경고를 출력하는 식으로 구현할 수 있을 것 같습니다. 이 개체는 모드 목록에 넣을 수 있습니다.
하지만 "가능한 최소한의 Privelige를 가지도록 권한을 주어야 한다"는 개체는 최소한의 Privelige에 대한 명확한 기준을 세우기 어려우므로 Steampipe를 이용해 자동화하기 어렵습니다. 이런 개체는 모드에서 제외하도록 합니다.
위 방식으로 벤치마크를 구현할 수 있는 Best-practice 7개를 선정했습니다.
- Do not grant basic roles unless there is no alternative.
- The best way to mitigate these threats is to avoid user-managed service account keys
- Ensure user-managed/external keys for service accounts are rotated every 90 days or less
- Use logs from Cloud Audit Logs to regularly audit changes to your IAM policy
- Manage access to logs using Logging roles.
- Grant roles to a Google group instead of individual users when possible
- Avoid using groups for granting service accounts access to resources
이제 각 개체의 준수 여부를 확인할 수 있는 쿼리문을 작성해야 합니다. 이 부분은 쿼리문을 작성하는 요령이 필요합니다.
쿼리문은 일반적인 쿼리문과 동일하게 구성하되, Steampipe 모드에서 요구하는 몇 가지 요구조건을 출력할 수 있어야 합니다.
이 중에는 row의 준수 여부를 확인하는 "status" 칼럼이 존재해야 하며, "status" 칼럼에는 "info", "alarm", "ok" 등의 정해진 값만 허용되는 등의 요구조건이 있습니다. 자세한 사항은 여기를 참고하시면 됩니다.
예를 들어 "User-managed service account key를 가급적 생성하면 안된다"라는 개체의 쿼리문을 아래와 같이 구성할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
select
row_number() over (order by service_account_name) as resource,
service_account_name,
key_type,
case
when key_type is not null then 'alarm'
else 'OK'
end status,
case
when key_type is not null then 'Avoid user-managed service account keys'
end reason
from gcp_service_account_key
where key_type = 'USER_MANAGED'
|
cs |
위 쿼리문은 "gcp_service_account_key" 테이블에서 "key_type" 칼럼 값이 'USER_MANAGED'인 것의 service_account_name 등을 출력합니다. 실행 결과는 다음과 같습니다.
이 쿼리문을 모드에 담아 실행할 시 아래와 같이 벤치마크 형식으로 결과를 출력하게 됩니다.
위의 쿼리문에서 볼 수 있듯이 기존 Postgresql의 문법을 사용해 쿼리문을 구성할 수 있습니다.
같은 방식으로 나머지 개체들의 쿼리문도 완성해 control 폴더에 담습니다.
아래는 구성한 쿼리문 중 "Audit log를 활성화해 관련 행위를 모니터링해야 한다" 개체를 구현한 쿼리문입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
with result as (
select
service,
case
when audit_log_configs #>> '{}' LIKE '%ADMIN_READ%' then 'On'
else 'Off'
end ADMIN_READ,
case
when audit_log_configs #>> '{}' LIKE '%DATA_READ%' then 'On'
else 'Off'
end DATA_READ,
case
when audit_log_configs #>> '{}' LIKE '%DATA_WRITE%' then 'On'
else 'Off'
end DATA_WRITE
from
gcp_audit_policy
where
service = 'iam.googleapis.com' or
service = 'sts.googleapis.com'
),
creation as (
select
UNNEST(array['iam.googleapis.com','sts.googleapis.com']) as service
from
gcp_iam_policy
),
joining as (
select
c.service as service,
case admin_read
when 'On' then 'On' else 'Off'
end admin_read,
case data_write
when 'On' then 'On' else 'Off'
end data_write,
case data_read
when 'On' then 'On' else 'Off'
end data_read
from
result as r
right join creation as c on r.service = c.service
),
pivot as (
select
j.service as service,
UNNEST(array['ADMIN_READ','DATA_READ','DATA_WRITE']) as type,
UNNEST(array[j.ADMIN_READ,j.DATA_READ,j.DATA_WRITE]) as stat
from joining as j
)
select
row_number() over (order by p.service) as resource,
case p.service
when 'iam.googleapis.com' then 'Identity and Access Management (IAM) API' else 'Security Token Service API'
end service,
p.type,
p.stat,
case p.stat
when 'On' then 'ok' else 'alarm'
end status,
case p.stat
when 'On' then 'Audit log is turned on' else 'Audit log should be turned on'
end reason
from pivot as p
|
cs |
아래와 같이 IAM과 Security token service API에 대한 Audigt log의 ADMIN_READ, DATA_READ, DATA_WRITE 유형 중 켜지지 않은 것이 있으면 Alarm을 출력합니다.
나머지 5개 개체들도 쿼리문을 작성해 control 폴더에 넣은 모습입니다.
그리고 워크스페이스의 루트 디렉토리에 "mod.sp" 파일을 생성한 후 아래 컨텐츠를 넣습니다.
1
2
3
4
5
6
7
8
|
mod "gcp_iam_report" {
# hub metadata
title = "GCP IAM Report"
description = "This Steampipe mod checks your GCP project(s) to check for GCP IAM best-practice compliances"
color = "#ea4335"
documentation = file("./docs/index.md")
categories = ["gcp","public cloud"]
}
|
cs |
모든 Steampipe 모드들은 이 mod.sp 파일이 존재해야 합니다. 모드 실행 시 이 파일을 참고해 control 폴더에 담긴 쿼리문을 실행하게 됩니다. 이 파일을 생성하는 것으로 Steampipe 모드를 구성할 수 있습니다.
이제 모드가 담긴 레포지토리를 가져오는 것으로 GCP IAM Report를 사용할 수 있습니다. 제가 제작한 GCP IAM Report 레포지토리는Public 레포지토리이므로 누구나 가져가서 사용할 수 있습니다.
아래 명령어로 GCP IAM Report 모드를 가져와서 사용할 수 있습니다.
1
|
git https://github.com/nangmans/steampipe_gcp_iam_report.git
|
cs |
이후 폴더로 이동해 "steampipe check all" 명령어를 입력하면 아래와 같이 프로젝트가 GCP iam best-practice를 준수했는지 확인할 수 있는 벤치마크를 실행합니다.
이런 방식으로 Steampipe 모드를 제작해 아이디어만 있다면 다양한 벤치마크를 구현할 수 있습니다.
5. 마치며
Steampipe는 퍼블릭 클라우드의 리소스에 관측 가능성을 확보할 수 있게 해주는 OSS 툴이었습니다.
Postgresql의 SQL 문법을 사용해 익숙한 방식으로 리소스를 조회할 수 있었으며 더 나아가 Compliance 준수 여부, 비용 절감 레포트, Best-practice 레포트 등의 심화 리소스 분석까지 가능했습니다.
여기에 Steampipe 모드를 이용해서 여러 쿼리를 벤치마크 형식으로 제작할 수 있게 해주는 방식을 지원해 편리하게 리소스 분석을 수행할 수 있었습니다.
추가적으로 제가 제작해본 GCP IAM Report 제작기를 바탕으로 Steampipe 모드를 어떻게 제작할 수 있는지까지 알아봤습니다.
GCP IAM Report에 대한 추가적인 아이디어가 개선점이 있다면 아래 링크의 제 레포지토리에 등록 부탁드립니다.
https://github.com/nangmans/steampipe_gcp_iam_report
'Observability' 카테고리의 다른 글
트레이싱 관측 도구 Grafana Tempo로 트레이스를 관측해보자 (0) | 2022.01.27 |
---|---|
Elasticsearch에 fluentd를 얹은 EFK stack 구축하기(with kubernetes) (9) | 2022.01.08 |
Elasticsearch의 ELK Stack을 GKE Cluster에 구성해 GCP 관측 가능성 확보하기 (6) | 2021.12.12 |
GKE Prometheus, Loki, Grafana로 Monitoring dashboard 구성하기(3) (0) | 2021.08.20 |
GKE Prometheus, Loki, Grafana로 Monitoring dashboard 구성하기(2) (0) | 2021.08.12 |