in cdk/jenkins/jenkins_leader.py [0:0]
def __init__(self, scope: core.Stack, id: str, cluster, vpc, worker, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
self.cluster = cluster
self.vpc = vpc
self.worker = worker
# Building a custom image for jenkins leader.
self.container_image = ecr.DockerImageAsset(
self, "JenkinsleaderDockerImage",
directory='./docker/leader/'
)
if config['DEFAULT']['fargate_enabled'] == "yes" or not config['DEFAULT']['ec2_enabled'] == "yes":
# Task definition details to define the Jenkins leader container
self.jenkins_task = ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
image=ecs.ContainerImage.from_docker_image_asset(self.container_image),
container_port=8080,
enable_logging=True,
environment={
# https://github.com/jenkinsci/docker/blob/leader/README.md#passing-jvm-parameters
'JAVA_OPTS': '-Djenkins.install.runSetupWizard=false',
# https://github.com/jenkinsci/configuration-as-code-plugin/blob/leader/README.md#getting-started
'CASC_JENKINS_CONFIG': '/config-as-code.yaml',
'network_stack': self.vpc.stack_name,
'cluster_stack': self.cluster.stack_name,
'worker_stack': self.worker.stack_name,
'cluster_arn': self.cluster.cluster.cluster_arn,
'aws_region': config['DEFAULT']['region'],
'jenkins_url': config['DEFAULT']['jenkins_url'],
'subnet_ids': ",".join([x.subnet_id for x in self.vpc.vpc.private_subnets]),
'security_group_ids': self.worker.worker_security_group.security_group_id,
'execution_role_arn': self.worker.worker_execution_role.role_arn,
'task_role_arn': self.worker.worker_task_role.role_arn,
'worker_log_group': self.worker.worker_logs_group.log_group_name,
'worker_log_stream_prefix': self.worker.worker_log_stream.log_stream_name
},
)
# Create the Jenkins leader service
self.jenkins_leader_service_main = ecs_patterns.ApplicationLoadBalancedFargateService(
self, "JenkinsleaderService",
cpu=int(config['DEFAULT']['fargate_cpu']),
memory_limit_mib=int(config['DEFAULT']['fargate_memory_limit_mib']),
cluster=self.cluster.cluster,
desired_count=1,
enable_ecs_managed_tags=True,
task_image_options=self.jenkins_task,
cloud_map_options=ecs.CloudMapOptions(name="leader", dns_record_type=sd.DnsRecordType('A'))
)
self.jenkins_leader_service = self.jenkins_leader_service_main.service
self.jenkins_leader_task = self.jenkins_leader_service.task_definition
if config['DEFAULT']['ec2_enabled'] == "yes":
self.jenkins_load_balancer = elb.ApplicationLoadBalancer(
self, "JenkinsleaderELB",
vpc=self.vpc.vpc,
internet_facing=True,
)
self.listener = self.jenkins_load_balancer.add_listener("Listener", port=80)
self.jenkins_leader_task = ecs.Ec2TaskDefinition(
self, "JenkinsleaderTaskDef",
network_mode=ecs.NetworkMode.AWS_VPC,
volumes=[ecs.Volume(name="efs_mount", host=ecs.Host(source_path='/mnt/efs'))],
)
self.jenkins_leader_task.add_container(
"JenkinsleaderContainer",
image=ecs.ContainerImage.from_ecr_repository(self.container_image.repository),
cpu=int(config['DEFAULT']['ec2_cpu']),
memory_limit_mib=int(config['DEFAULT']['ec2_memory_limit_mib']),
environment={
# https://github.com/jenkinsci/docker/blob/leader/README.md#passing-jvm-parameters
'JAVA_OPTS': '-Djenkins.install.runSetupWizard=false',
# https://github.com/jenkinsci/configuration-as-code-plugin/blob/leader/README.md#getting-started
'CASC_JENKINS_CONFIG': '/config-as-code.yaml',
'network_stack': self.vpc.stack_name,
'cluster_stack': self.cluster.stack_name,
'worker_stack': self.worker.stack_name,
'cluster_arn': self.cluster.cluster.cluster_arn,
'aws_region': config['DEFAULT']['region'],
'jenkins_url': config['DEFAULT']['jenkins_url'],
'subnet_ids': ",".join([x.subnet_id for x in self.vpc.vpc.private_subnets]),
'security_group_ids': self.worker.worker_security_group.security_group_id,
'execution_role_arn': self.worker.worker_execution_role.role_arn,
'task_role_arn': self.worker.worker_task_role.role_arn,
'worker_log_group': self.worker.worker_logs_group.log_group_name,
'worker_log_stream_prefix': self.worker.worker_log_stream.log_stream_name
},
logging=ecs.LogDriver.aws_logs(
stream_prefix="Jenkinsleader",
log_retention=logs.RetentionDays.ONE_WEEK
),
)
self.jenkins_leader_task.default_container.add_mount_points(
ecs.MountPoint(
container_path='/var/jenkins_home',
source_volume="efs_mount",
read_only=False
)
)
self.jenkins_leader_task.default_container.add_port_mappings(
ecs.PortMapping(
container_port=8080,
host_port=8080
)
)
self.jenkins_leader_service = ecs.Ec2Service(
self, "EC2leaderService",
task_definition=self.jenkins_leader_task,
cloud_map_options=ecs.CloudMapOptions(name="leader", dns_record_type=sd.DnsRecordType('A')),
desired_count=1,
min_healthy_percent=0,
max_healthy_percent=100,
enable_ecs_managed_tags=True,
cluster=self.cluster.cluster,
)
self.target_group = self.listener.add_targets(
"JenkinsleaderTarget",
port=80,
targets=[
self.jenkins_leader_service.load_balancer_target(
container_name=self.jenkins_leader_task.default_container.container_name,
container_port=8080,
)
],
deregistration_delay=core.Duration.seconds(10)
)
# Opening port 5000 for leader <--> worker communications
self.jenkins_leader_service.task_definition.default_container.add_port_mappings(
ecs.PortMapping(container_port=50000, host_port=50000)
)
# Enable connection between leader and Worker
self.jenkins_leader_service.connections.allow_from(
other=self.worker.worker_security_group,
port_range=ec2.Port(
protocol=ec2.Protocol.TCP,
string_representation='leader to Worker 50000',
from_port=50000,
to_port=50000
)
)
# Enable connection between leader and Worker on 8080
self.jenkins_leader_service.connections.allow_from(
other=self.worker.worker_security_group,
port_range=ec2.Port(
protocol=ec2.Protocol.TCP,
string_representation='leader to Worker 8080',
from_port=8080,
to_port=8080
)
)
# IAM Statements to allow jenkins ecs plugin to talk to ECS as well as the Jenkins cluster #
self.jenkins_leader_task.add_to_task_role_policy(
iam.PolicyStatement(
actions=[
"ecs:RegisterTaskDefinition",
"ecs:DeregisterTaskDefinition",
"ecs:ListClusters",
"ecs:DescribeContainerInstances",
"ecs:ListTaskDefinitions",
"ecs:DescribeTaskDefinition",
"ecs:DescribeTasks"
],
resources=[
"*"
],
)
)
self.jenkins_leader_task.add_to_task_role_policy(
iam.PolicyStatement(
actions=[
"ecs:ListContainerInstances"
],
resources=[
self.cluster.cluster.cluster_arn
]
)
)
self.jenkins_leader_task.add_to_task_role_policy(
iam.PolicyStatement(
actions=[
"ecs:RunTask"
],
resources=[
"arn:aws:ecs:{0}:{1}:task-definition/fargate-workers*".format(
self.region,
self.account,
)
]
)
)
self.jenkins_leader_task.add_to_task_role_policy(
iam.PolicyStatement(
actions=[
"ecs:StopTask"
],
resources=[
"arn:aws:ecs:{0}:{1}:task/*".format(
self.region,
self.account
)
],
conditions={
"ForAnyValue:ArnEquals": {
"ecs:cluster": self.cluster.cluster.cluster_arn
}
}
)
)
self.jenkins_leader_task.add_to_task_role_policy(
iam.PolicyStatement(
actions=[
"iam:PassRole"
],
resources=[
self.worker.worker_task_role.role_arn,
self.worker.worker_execution_role.role_arn
]
)
)