Woori FIS · AWS · Security
Woori Financial Group AWS security architecture
Moved network separation requirements across multiple AWS accounts into subnet and firewall structure, and standardized security settings as one set of Terraform code.
- Role
- Cloud Security Engineer · Network Security team, Information Security
- Period
- Feb 2026 – Oct 2026
- Cloud
- AWS
- Scale
- Multiple AWS accounts
- Key tech
- Terraform · AWS Network Firewall · AWS WAF · AWS Shield Standard · GuardDuty · Security Hub · Splunk · Python
- 5
- Security services connected to Splunk SIEM/SOAR
- 3
- Design principles from network separation
- 1
- Set of Terraform code across multiple AWS accounts
At a glance
Problem
Group companies were adopting public cloud for the first time, with no Terraform in place, and security settings varied by account and by person. Network separation rules were hard to hold in documents alone.
Approach
Network separation (a Korean financial regulation) became three design principles: separate DMZ and Private subnets, no public IP on backends, and outbound only to allowed destinations. WAF, Network Firewall, and Shield Standard are defined in Terraform and applied through the same code to every account, with GuardDuty and Security Hub connected to Splunk SIEM/SOAR.
Result
The same security standard repeats through code as accounts grow, and per-person differences are gone. A Python pipeline now collects and analyzes network configuration across multiple AWS accounts, so review is repeatable. IAM permissions are defined in Terraform as well, which structurally blocks excessive grants.
Up close
Computing network coverage (related public repository pf-09)
What this code does: Computes which address ranges no rule covers. This is code from a related public repository, not the production code of this project.
def uncovered_networks(
targets: Iterable[ipaddress.IPv4Network], rule_cidrs: Iterable[str]
) -> list[ipaddress.IPv4Network]:
"""The parts of the targets that no rule reaches."""
remaining = list(targets)
for cidr in rule_cidrs:
try:
rule = ipaddress.IPv4Network(cidr, strict=False)
except ValueError:
continue
next_round: list[ipaddress.IPv4Network] = []
for network in remaining:
if network.subnet_of(rule):
continue
if rule.subnet_of(network):
next_round.extend(network.address_exclude(rule))
else:
next_round.append(network)
remaining = next_round
return remainingWhat I learned
When security settings are code, differences between accounts show up as code differences. There is no need to compare settings one by one.
What I would improve
Shield ran in the Standard tier. Next, I want to automate the check that the coded standard actually holds in each account.