Jenkins 배포하기
Jenkins 배포 핵심
Jenkins 배포에서 중요한 것은 EFS 활용과 Userdata 부분입니다. ALB + Autoscaling 을 생성하는 부분은 앞선 실습에서 했기 때문에 이번 실습에서는 생략하겠습니다.
3. 어플리케이션 서비스 만들기Elastic File System 생성
Terraform으로 Elastic file system을 생성합니다.
생성된 EFS의 Domain name은 Instance의 Userdata에서 참조됩니다.
# Security Group for EFS
## Should allow Jenkins Instance ONLY!!!
resource "aws_security_group" "efs" {
name = "${var.service_name}-efs-${var.vpc_name}"
description = "${var.service_name} efs sg for ${var.vpc_name}"
vpc_id = var.target_vpc
ingress {
from_port = 2049 # for NFS
to_port = 2049
protocol = "tcp"
security_groups = [
# EC2 Instance Security Group
aws_security_group.ec2.id,
]
}
tags = {
Name = "${var.service_name}-efs-${var.vpc_name}"
}
}
resource "aws_efs_file_system" "file_system" {
tags = {
Name = "${var.service_name}-efs-${var.vpc_name}"
}
#You can control this value through variable
provisioned_throughput_in_mibps = var.efs_provisioned_throughput_in_mibps
#You can control this mode through variable
throughput_mode = var.efs_throughput_mode
}
resource "aws_efs_mount_target" "mount_target" {
# If you do not have NAT gateway or NAT instance in private subnets,
# You should deploy jenkins to public subnet!
count = length(var.private_subnets)
#count = length(var.public_subnets)
file_system_id = aws_efs_file_system.file_system.id
subnet_id = element(var.private_subnets, count.index)
#subnet_id = element(var.public_subnets, count.index)
security_groups = [
aws_security_group.efs.id,
]
}
User data 정의
Userdata에 efs 도메인 이름을 참조하기 위해서 테라폼의
template_file
을 활용합니다.
먼저 userdata.sh.tpl
을 살펴보겠습니다. Userdata에서 배포에 필요한 기본 패키지를 설치하고, 생성된 EFS를 /var/lib/jenkins
에mount합니다.
#!/bin/bash -ex
function waitForJenkins() {
echo "Waiting jenkins to launch on 8080..."
while ! nc -z localhost 8080; do
sleep 0.1 # wait for 1/10 of the second before check again
done
echo "Jenkins launched"
}
function waitForPasswordFile() {
echo "Waiting jenkins to generate password..."
while [ ! -f /var/lib/jenkins/secrets/initialAdminPassword ]; do
sleep 2 # wait for 1/10 of the second before check again
done
echo "Password created"
}
amazon-linux-extras install corretto8
yum update -y
yum install -y jq git awscli nmap-ncat nfs-common
export JENKINS_HOME=/var/lib/jenkins
mkdir -p $JENKINS_HOME
mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${efs_dns_name}:/ $JENKINS_HOME
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
yum install -y jenkins
sed -i 's/Djava.awt.headless=true/Djava.awt.headless=true -Xmx2G -Xms2G -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia\/Seoul/g' /etc/sysconfig/jenkins
service jenkins start
위에서 정의한 user_data
파일은 template_file
형태로 참조합니다. 변수로는 EFS dns_name을 넘겨줍니다.
data "template_file" "init" {
template = "${file("${path.module}/scripts/userdata.sh.tpl")}"
vars = {
efs_dns_name = aws_efs_file_system.file_system.dns_name
}
}
Module 사용 부분
Jenkins 전체 세트는 Module을 통해서 정의하고, 실제 변수들은 환경에 따라 다르게 세팅합니다.
terraform/platform/jenkins/<환경>
directory를 통째로 복사해서 새로운 환경 변수를 정의하면, 동일한 jenkins 세트를 생성하실 수 있습니다.배포하는 리전이 서울(ap-northeast-2)가 아니면,
terraform.tfvars
파일에서jenkins_master_ami
를 해당 리전의 AMI ID로 변경해주시기 바랍니다.(Amazon Linux 2)External LB는 보안을 위해서
반드시 내부망만 오픈
하시기 바랍니다!!!Github Webhook을 사용하는 경우에는 퍼블릭으로 오픈하지 마시고, https://api.github.com/meta 사이트에서 hook 서버 IP들만 오픈하시는 것을 추천드립니다.
또 webhook을 보내더라도 바로 jenkins로 보내지 마시고, API Gateway + Lambda 등을 중간에 두고 인증절차를 거치시기 바랍니다.
module "jenkins" {
source = "../_module/jenkins"
service_name = "jenkins"
service_port = 8080
healthcheck_port = 8080
account_id = var.account_id.prod
shard_id = data.terraform_remote_state.vpc.outputs.shard_id
public_subnets = data.terraform_remote_state.vpc.outputs.public_subnets
private_subnets = data.terraform_remote_state.vpc.outputs.private_subnets
aws_region = data.terraform_remote_state.vpc.outputs.aws_region
target_vpc = data.terraform_remote_state.vpc.outputs.vpc_id
vpc_name = data.terraform_remote_state.vpc.outputs.vpc_name
vpc_cidr_numeral = data.terraform_remote_state.vpc.outputs.cidr_numeral
route53_internal_domain = data.terraform_remote_state.vpc.outputs.route53_internal_domain
route53_internal_zone_id = data.terraform_remote_state.vpc.outputs.route53_internal_zone_id
billing_tag = data.terraform_remote_state.vpc.outputs.billing_tag
newrelic_monitor = "false"
ssh_key_name = "dayone-prod-master"
instance_ami = var.jenkins_master_ami
tag_first_owner = var.tag_first_owner
tag_second_owner = var.tag_second_owner
tag_project = var.tag_project
efs_provisioned_throughput_in_mibps = 0
#KMS Key for deployment
deployment_common_arn = data.terraform_remote_state.kms.outputs.aws_kms_key_prod_apne2_deployment_common_arn
# Instance Count Variables
instance_count_max = 1
instance_count_min = 1
instance_count_desired = 1
# Route53 variables
acm_external_ssl_certificate_arn = var.r53_variables.prod.star_dayonedevops_com_acm_arn_apnortheast2
route53_external_zone_id = var.r53_variables.prod.dayonedevops_com_zone_id
domain_name = "jenkins"
# Resource LoadBalancer variables
lb_variables = var.lb_variables
# Security Group variables
sg_variables = var.sg_variables
# Home Security Group via remote_state
home_sg = data.terraform_remote_state.vpc.outputs.aws_security_group_home_id
#github_hook_sg = data.terraform_remote_state.vpc.outputs.aws_security_group_github_hook_id
github_hook_sg = ""
# CIDR for external LB
# Control allowed IP for external LB
ext_lb_ingress_cidrs = [
"0.0.0.0/0"
]
}
배포 후 세팅
Jenkins를 배포하고 나면 Route53 URL을 통해서 Jenkins에 접속하실 수 있습니다.
홈페이지에 접속하시면 아래와 같이 init password를 입력하라고 나옵니다.
배포된 인스턴스에 접속하셔서 웹페이지에 적힌 path 파일에서 패스워드를 얻으신 후에 붙여넣으시면 됩니다.
Instance 접속은 bastion host -> instance로 하셔도 되고, aws sessions manager를 통해서 접속하실 수도 있습니다.
SSM 접속을 위한 기본적인 Permission은 이미 IAM Role에 들어 있습니다.
[root@ip-10-20-19-82 ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
04369ed0856c4f7bad4c64dde084cae9

이후에 설치를 진행합니다. 원하시는 메뉴로 설치를 진행하시기 바랍니다.

Last updated
Was this helpful?