AWS Config 정책을 코드로 작성해서 관리하고, 재사용이 가능하도록 terraform 으로 구현해보자!
Managed rule 생성
aws config에서 기본적으로 사용할 수 있는 정책들이다. 웬만한 정책들은 제공해주고 있는 것 같다.. 비용적인 부분을 고려해서 필요한 룰들만 검토해서 사용하면 된다.
resource "aws_config_config_rule" "api-gw-endpoint-type-check" {
count = var.api-gw-endpoint-type-check ? 1 : 0
name = "api-gw-endpoint-type-check"
description = "Checks if Amazon API Gateway APIs are of the type specified in the rule parameter endpointConfigurationType. The rule returns NON_COMPLIANT if the REST API does not match the endpoint type configured in the rule parameter."
input_parameters = local.api-gw-endpoint-type-check
source {
owner = "AWS"
source_identifier = "API_GW_ENDPOINT_TYPE_CHECK"
}
tags = var.tags
}
variable "api-gw-endpoint-type-check" {
description = "api-gw-endpoint-type-check"
type = bool
}
- count
0일 경우 리소스가 생성되지 않는다. var.api-gw-endpoint-type-check 변수가 true일 때 1을, false일 때 0을 반환한다.
variable 내에 default를 별도로 명시해놓지 않으면 terraform apply 명령 시 에러가 발생한다는 걸 이용해서 config 모듈을 import해서 사용하는 경우에 필수로 적용해야 할 정책을 만들 수 있다.
- name
정책 이름을 작성한다. - description
정책 내용을 작성한다. - input_parameters
정책에서 사용할 파라미터를 입력한다. 아래 docs에서 정책별로 필요한 파라미터를 보고 가져다 쓰면된다.
https://docs.aws.amazon.com/config/latest/developerguide/managed-rules-by-aws-config.html - source{}
managed rule의 Identifier를 가져와서 입력한다.
각 정책별로 입력되는 파라미터를 유연하게 수정할 수 있도록 local 변수로 관리한다.
# /config-policies/api-gw-endpoint-type-check.tpl
{
"endpointConfigurationTypes": "${api-gateway-endpoint-type}"
}
# main.tf
locals {
api-gw-endpoint-type-check = templatefile("${path.module}/config-policies/api-gw-endpoint-type-check.tpl",
{
api-gateway-endpoint-type = var.api-gateway-endpoint-type
}
)
}
# variables.tf
variable "api-gateway-endpoint-type" {
description = "ApiGateway Endpoint type"
type = string
default = "PRIVATE"
}
입력해야 할 파라미터를 별도의 템플릿파일에 작성하고, 변수를 입력받는다.
=> 추후 필요 시 파라미터 값을 별도로 입력하게 할 수 있다.
Custom rule 생성
자기 입맛대로 custom한 rule을 생성하고 싶을 때 아래 두 가지 방법중 하나를 선택하면 된다.
1. Lambda 를 생성해서 정책 작성 -> aws config 정책 하나 + 람다 하나
2. cloudformation guard 로 정책 작성 -> aws config 정책 하나
1번의 경우는 람다를 하나 추가로 생성해줘야 되서 guard 로 작성하는게 관리측면에서 더 나아보인다.
ALB가 internal인 경우에만 정책을 PASS 하도록 작성해봤다.
rule LoadBalancer when
resourceType == "AWS::ElasticLoadBalancingV2::LoadBalancer" {
configuration.scheme == 'internal'
}
코드 작성은 Guard 문법을 보면서 작성해야 하고 리소스이름,ID,설정과 같은 내용의 경우 aws에서 스키마를 따로 제공해준다.
테라폼 코드로 작성하기 전에 aws 콘솔상에서 rule을 작성해보고, debug 로그를 보면서 의도한대로 잘 동작하는지 확인해봐야 한다.
guard rule 작성을 완료했으면, Managed rule과 같은 방법으로 terraform resource로 생성하면 된다.
아래 코드예시는 terraform docs에서 가져온 내용이다.
resource "aws_config_config_rule" "example" {
name = "example"
source {
owner = "CUSTOM_POLICY"
source_detail {
message_type = "ConfigurationItemChangeNotification"
}
custom_policy_details {
policy_runtime = "guard-2.x.x"
policy_text = <<EOF
rule tableisactive when
resourceType == "AWS::DynamoDB::Table" {
configuration.tableStatus == ['ACTIVE']
}
rule checkcompliance when
resourceType == "AWS::DynamoDB::Table"
tableisactive {
supplementaryConfiguration.ContinuousBackupsDescription.pointInTimeRecoveryDescription.pointInTimeRecoveryStatus == "ENABLED"
}
EOF
}
}
}
policy_text 부분에 guard rule을 입력해야 하는데, rule 길이가 길어질 수록 가독성은 떨어진다..
이 부분도 매개변수 관리하는것과 동일하게 별도 템플릿파일에 rule을 작성해서 불러다 쓰면 가독성이 좋을 것 같다.
custom_policy_details {
policy_runtime = "guard-2.x.x"
policy_text = templatefile("${path.module}/config-policies/custom_policy.tpl", {})
}
적용해보기
적용하고 싶은 Rule을 불러와 사용한다.
module "config" {
source = "../"
config_name = var.config_name
api-gw-endpoint-type-check = true
restrict-internet-alb = true
tags = {
"Automation" = "Terraform"
"Name" = var.config_name
}
}
terraform plan & terraform apply 이후 AWS 콘솔에서 확인해보면 정책이 잘 생성된 것을 확인할 수 있다!
api-gw-endpoint 정책에 파라미터도 잘 적용되어 있는 걸 볼 수 있다.
관리하고 있는 계정이 많아질수록 어느 계정에 적용된 규칙이 무엇인지, 규칙 별 옵션은 어떻게 들어가있는지 파악하기가 쉽지 않다.
이럴 때 terraform을 통해서 config 규칙들을 작성해놓고 모듈화해서 사용하면 컴플라이언스 관리에 많은 도움이 될 것 같다.
ref.
https://github.com/trussworks/terraform-aws-config
'AWS' 카테고리의 다른 글
Organization 환경에서 AWS Config 적용 (0) | 2023.08.08 |
---|---|
RDS CCE 취약점 진단하기 (0) | 2023.08.06 |
Multi-Account 환경에서 사용중인 서비스 조회 (0) | 2023.08.06 |