반응형
요약
- CSV파일 + Terraform 으로 SG 관리하는 법 정리
- 하면서 알게된 팁 및 내용들 정리
목적 및 고려 사항
- AWS-GUI를 통해 SG를 관리하게 되면, 변경할 때 불편사항이 많다. (클릭이 귀찮음..)
- Terraform을 통해 IaC로 인프라를 관리하게 될 경우, SG-Rule을 하나 추가할 때 마다 번잡한 코드가 많아짐 (대략 1개 SG-rule 추가 할 때 마다 최소 5줄은 필요)
- CSV형식으로 SG-Rule을 관리하기 편하게 해보자
내용
- AWS에서 SG가져오는 코드
"""
1. 정보를 가져와서 CSV만들기 (EC2)
- aws-cli가 되는 프로필 설정은 먼저 해놓기
"""
import json
import boto3
import csv
from botocore.config import Config
input = dict()
# aws-cli가 되는 프로파일 설정은 먼저 해놓기
input['servicetag'] = 'test'
input['region_name'] = 'ap-northeast-2'
input['enviorment'] = 'production'
# 호출부 (전체 리스트)
def get_sg_list():
my_config = Config(
region_name = input['region_name']
)
client = boto3.client('ec2', config=my_config)
res = client.describe_security_groups(
Filters=[
{
'Name': 'tag:servicetag',
'Values' : [
input['servicetag']
],
'Name': 'tag:Environment',
'Values' : [
input['enviorment']
]
}
]
)
print (len(res['SecurityGroups']))
return res
# 보안 그룹 개수 체크하는 것
def write_sg_list_json():
file_path_json="/custom_path/sg.json"
res = get_sg_list()
with open(file_path_json, 'w') as outfile:
json.dump(res['SecurityGroups'], outfile)
def make_csv():
file_path_csv="/custom_path/"+input['enviorment']+".csv"
with open(file_path_csv,'w',newline="") as outfile:
wr = csv.writer(outfile)
wr.writerow(['key','sg_name','rule_type','protocol','from_port','to_port','src','description'])
return
# json 데이터 -> csv 변환
# 데이터 : key(Auto Increase),sg_name,rule_type,protocol, from_port, to_port, src, description
# key 값이 뽑을 때 마다 달라질 수 있음 (3. 업데이트 치는 기능 만들기 )
def update_make_csv(key,sg_name,rule_type,protocol,from_port,to_port,src,description):
file_path_csv="/custom_path/"+input['enviorment']+".csv"
with open(file_path_csv,'a',newline="") as outfile:
wr = csv.writer(outfile)
wr.writerow([key,sg_name,rule_type,protocol,from_port,to_port,src,description])
return
def make_json_to_csv():
res = get_sg_list()
make_csv()
for sg in res['SecurityGroups']:
key=0
sg_name=sg['GroupName']
for sg_rule_ingress in sg['IpPermissions']:
protocol = sg_rule_ingress['IpProtocol']
from_port = sg_rule_ingress['FromPort']
to_port = sg_rule_ingress['ToPort']
for IpRange in sg_rule_ingress['IpRanges']:
src = IpRange['CidrIp']
desc = IpRange['Description']+"(CSV)"
key += 1
update_make_csv(key,sg_name,'ingress',protocol,from_port,to_port,src,desc)
for sg_rule_egress in sg['IpPermissionsEgress']:
protocol = sg_rule_egress['IpProtocol']
from_port = sg_rule_egress['FromPort']
to_port = sg_rule_egress['ToPort']
for IpRange in sg_rule_egress['IpRanges']:
src = IpRange['CidrIp']
desc = IpRange['Description']+"(CSV)"
key += 1
update_make_csv(key,sg_name,'egress',protocol,from_port,to_port,src,desc)
return
# 실행
make_json_to_csv()
- 출력 CSV 예시
key,rule_type,protocol,from_port,to_port,src,description
1,ingress,tcp,0,65000,0.0.0.0/0,All Allow Ingress
2,egress,tcp,80,443,0.0.0.0/0,All Allow Egress
- Terraform 적용 코드
resource "aws_security_group" "allow_bastion_sg_csv" {
name = format("%s_bastion_csv_sg", var.name_prefix)
vpc_id = var.vpc_id
}
resource "aws_security_group_rule" "allow_bastion_firewall_csv" {
for_each = true ? { for csv in local.sg_rules : csv.key => csv } : {}
type = each.value.rule_type
from_port = each.value.from_port
to_port = each.value.to_port
protocol = each.value.protocol
cidr_blocks = [each.value.src]
security_group_id = aws_security_group.allow_bastion_sg_csv.id
description = each.value.description
lifecycle {
create_before_destroy = true
}
}
추가 팁 정리
- CSV 안에 Key값을 두게 되면, tfstate 내에 일종의 SG-rule의 키 값으로 테라폼에서 관리
- Key값이 없을 경우 SG-rule을 Array형태로 관리하기 때문에 하나만 변동 되어도, 전체 Replace수행 예상 (테스트는 필요)
- 같은 키 값의 사항에 변경 사항이 생기면 -/+로 Replace가 생기고, 다른 키 값으로 만들면 + 즉 add가 됨
- 중복되는 값이 있을 경우, terraform apply 시에 중복 된 것에 대해 에러코드를 출력함
- 별도의 관리 정책을 통해, 바로 이전 정상 상태로 원복이 가능하고, 코드 레벨로 SG-Rule 변경 사항을 계속 트랙킹 할 수 있다
- lifecycle에 create_before_destory를 적용해놓으면 +/-의 형태로 변경된다.
- AMQP... SG Change가 안된다 (이건 좀..)
해볼 것
- Terraform Resource가 현재 SecurityGroup와 SecrutityGroupRule로 나누어져 있는 데, 이것을 SecurityGroup으로 모두 합칠 지 테스트 필요
- 변동할 경우 -/+되는 상황이 발생하는 지
- Replace 상황에서 순단이 발생하는 지 확인 필요
참고자료
728x90
반응형
'Devops 솔루션 > Terraform' 카테고리의 다른 글
[Terraform] terraform_remote_state 이란 (0) | 2023.03.23 |
---|---|
[Terraform] for_each, for loop 란 (0) | 2023.03.05 |