AWS Fargate를 사용해 jenkins master <-> agent를 구성해보자. Part 2.
목차.
- https://hwan-shell.tistory.com/375 (Jenkins ECS Fargate 설명)
- https://hwan-shell.tistory.com/376 (네트워크 구축)
- https://hwan-shell.tistory.com/377 (ECS, Cloud Map, EFS 구축)
- https://hwan-shell.tistory.com/378 (Jenkins Node 설정 및 테스트)
이번장에선 AWS Fargate, Cloud Map, EFS 셋팅을 해보겠습니다.
우선 Fargate에서 사용할 Cloud Map를 구현합니다.
1. AWS Cloud Map
# Define Jenkins Cloud Map
resource "aws_service_discovery_private_dns_namespace" "jenkins" {
name = "local.com"
vpc = var.jenkins_vpc_id
description = "Jenkins Cloud Map"
tags = {
Name = "Jenkins Cloud Map"
}
}
resource "aws_service_discovery_service" "jenkins" {
name = "jenkins"
dns_config {
namespace_id = aws_service_discovery_private_dns_namespace.jenkins.id
dns_records {
ttl = 60
type = "A"
}
routing_policy = "MULTIVALUE"
}
health_check_custom_config {
failure_threshold = 1
}
tags = {
Name = "Jenkins Cloud Map"
}
}
Master와 Agent가 통신을 할 때 필요한 Private DNS 설정입니다.
내부적으로 사용될 DNS이므로, 도메인 등록, DNS validation 과정은 필요 없습니다.
2. AWS EFS
# Define Jenkins EFS
resource "aws_efs_file_system" "jenkins" {
creation_token = "jenkins-efs"
tags = {
Name = "Jenkins EFS"
}
}
resource "aws_efs_mount_target" "jenkins" {
for_each = var.jenkins_vpc_private_subnet_ids
file_system_id = aws_efs_file_system.jenkins.id
subnet_id = each.value
security_groups = [
var.jenkins_efs_sg_id
]
}
resource "aws_efs_access_point" "jenkins" {
file_system_id = aws_efs_file_system.jenkins.id
posix_user {
uid = 1000
gid = 1000
}
root_directory {
path = "/jenkins-home"
creation_info {
owner_gid = 1000
owner_uid = 1000
permissions = "0755"
}
}
tags = {
Name = "Jenkins EFS Access Point"
}
}
위와 같이 EFS를 정의합니다. aws_efs_access_point의 root_directory에 있는 path는 마운트할 때 지정된 경로이므로 자유롭게 설정하면 됩니다.
해당 access point를 사용해 Fargate가 EFS에 접근할 수 있게 됩니다.
3. AWS ECS Fargate
ECS Fargate를 사용하여 Master <-> Agent 구조를 만듭니다.
resource "aws_ecs_cluster" "jenkins" {
name = "jenkins-cluster"
setting {
name = "containerInsights"
value = "enabled"
}
tags = {
Name = "Jenkins ECS Cluster"
}
}
resource "aws_ecs_task_definition" "jenkins" {
for_each = var.jenkins_tasks
family = each.value.family
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 1024
memory = 2048
execution_role_arn = var.jenkins_ecs_task_execution_role_arn
task_role_arn = var.jenkins_ecs_task_role_arn
container_definitions = jsonencode([
{
name = each.key
image = each.value.image
essential = true
portMappings = [
{
containerPort = var.jenkins_port
hostPort = var.jenkins_port
protocol = "tcp"
},
{
containerPort = var.jenkins_jnlp
hostPort = var.jenkins_jnlp
protocol = "tcp"
},
{
containerPort = var.http
hostPort = var.http
protocol = "tcp"
},
{
containerPort = var.https
hostPort = var.https
protocol = "tcp"
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = aws_cloudwatch_log_group.jenkins_ecs.name
awslogs-region = "ap-northeast-2"
awslogs-stream-prefix = each.value.awslogs_prefix
}
}
mountPoints = [
{
containerPath = "/var/jenkins_home"
sourceVolume = "jenkins_home"
}
]
}
])
volume {
name = "jenkins_home"
efs_volume_configuration {
file_system_id = var.jenkins_efs_id
transit_encryption = "ENABLED"
authorization_config {
access_point_id = var.jenkins_efs_access_point_id
iam = "ENABLED"
}
}
}
}
resource "aws_ecs_service" "jenkins" {
name = "jenkins-service"
cluster = aws_ecs_cluster.jenkins.id
task_definition = aws_ecs_task_definition.jenkins["jenkins-master"].arn
desired_count = 1
launch_type = "FARGATE"
deployment_maximum_percent = 100
deployment_minimum_healthy_percent = 0
network_configuration {
subnets = local.private_subnets
security_groups = [var.jenkins_ecs_sg_id]
assign_public_ip = false
}
load_balancer {
target_group_arn = var.jenkins_alb_target_group_arn
container_name = "jenkins-master"
container_port = var.jenkins_port
}
service_registries {
registry_arn = var.jenkins_discovery_service_arn
}
tags = {
Name = "Jenkins ECS Service"
}
}
Task definition 을 정의할 때 Mount할 EFS를 등록해 줍니다.
그리고 ECS Service의 service_registries에 Cloud Map에 정의한 discovery service 정보를 넣어줍니다.
discovery service는 Amazon Route 53에서 사용할 수 있는 서비스 디스커버리를 통해 자동으로 검색하고 연결할 수 있도록 도와주는 구성 요소입니다.
이걸 ECS에 적용시키면 Docker간 통신을 IP주소 없이 Domain name으로 통신할 수 있게 됩니다.
정상적으로 ECS에 등록이 되면 위 사진과 같이 Route 53에 호스팅 영역으로 만든 이름이 나오게 됩니다.
그 외 Master <-> Agent와 통신할 수 있도록 8080, 50000포트를 열어둔 후 ECS에서 사용할 IAM rule, policy를 설정한 후 구성하면 됩니다.
여기서 추가적인 코드를 참고하시기 바랍니다.
https://github.com/dnfwlq8054/jenkins_in_fargate
Route 53에 외부에서 사용할 도메인을 구매하지 않았기 때문에, 80포트로 ALB DNS주소에 접속합니다.
처음 비밀번호는 Cloud Watch에 log를 보면 확인이 가능 합니다.
ALB에 나와있는 DNS name으로 http 접속을 합니다.
이렇게 하면 구축한 jenkins에 접속할 수 있습니다.
다음 Part 3에서는 Agent를 실행하는 설정과 방법에 대해 설명하겠습니다.