cloud-config.yaml (281 lines of code) (raw):

#cloud-config write_files: - path: "/etc/teamcity/update.sh" permissions: 0755 content: | #!/bin/bash while true do STATUS=$(curl -s -o /etc/teamcity/tags -w '%{http_code}' -H Metadata:true "http://169.254.169.254/metadata/instance/compute/tags?api-version=2017-08-01&format=text") if [ $STATUS -eq 200 ]; then VERSION=$(cat /etc/teamcity/tags | sed -n 's/.*teamcity-version\:\([^;]\+\).*/\1/p') if [[ ! -z "$VERSION" ]]; then TEAMCITY_VERSION="TEAMCITY_VERSION=$VERSION" CURRENT_VERSION=$(at /etc/teamcity/version) if [ "$TEAMCITY_VERSION" != "$CURRENT_VERSION" ]; then echo "TeamCity version has changed to $VERSION" echo "$TEAMCITY_VERSION" > /etc/teamcity/version /usr/bin/docker pull jetbrains/teamcity-server:${VERSION} /usr/bin/docker pull jetbrains/teamcity-agent:${VERSION} fi fi fi sleep 60 done - path: "/etc/teamcity/database.properties" content: | # Database: MySQL connectionUrl=jdbc:mysql://%RDSHost%/%RDSDataBase%?useSSL=true&requireSSL=false connectionProperties.user=teamcity@%RDSHost% connectionProperties.password=%RDSPassword% maxConnections=50 testOnBorrow=true - path: "/etc/teamcity/disabled-plugins.xml" content: | <?xml version="1.0" encoding="UTF-8"?> <disabled-plugins> <disabled-plugin name="cloud-amazon" /> <disabled-plugin name="s3-artifact-storage" /> <disabled-plugin name="vsphere" /> </disabled-plugins> - path: "/etc/teamcity/hostname" content: | DOMAIN_NAME=%DomainName% - path: "/etc/teamcity/check-certificate.sh" permissions: 0755 content: | #!/bin/bash attempt=0 while docker exec letsencrypt /app/cert_status | grep ${DOMAIN_NAME} > /dev/null; [[ $? -ne 0 ]]; do retry_in_mins=$((3**$attempt)) echo "Will try to renew certificate for ${DOMAIN_NAME} in $retry_in_mins minutes" sleep $((60 * $retry_in_mins)) echo "Trying to renew certificate for ${DOMAIN_NAME}..." docker exec letsencrypt /app/signal_le_service sleep 30 attempt=$(($attempt + 1)) done - path: "/etc/teamcity/download-file.sh" permissions: 0755 content: | #!/bin/bash attempt=0 until $(curl --output $2 --silent --fail $1); do retry_in_secs=$((3**$attempt)) echo "Will try to download file $1 in $retry_in_secs minutes" sleep $retry_in_secs echo "Trying to download file $1..." attempt=$(($attempt + 1)) done - path: "/etc/flatcar/update.conf" content: | REBOOT_STRATEGY="off" flatcar: units: - name: "format-mnt-data.service" enable: true content: | [Unit] Requires=network-online.target Before=teamcity-server.service mnt-data.mount RequiresMountsFor=/dev/mapper ConditionPathExists=!/dev/mapper/app-data [Service] Type=oneshot ExecStart=/bin/bash -c \ '/usr/sbin/pvcreate /dev/disk/azure/scsi1/lun0 && \ /usr/sbin/vgcreate app /dev/disk/azure/scsi1/lun0 && \ /usr/sbin/lvcreate -l 100%%FREE -n data app && \ /usr/sbin/mkfs.ext4 /dev/mapper/app-data' [Install] WantedBy=multi-user.target - name: "mnt-data.mount" enable: true content: | [Unit] Before=teamcity-server.service After=format-mnt-data.service Requires=format-mnt-data.service ConditionVirtualization=!container Conflicts=umount.target [Mount] What=/dev/mapper/app-data Where=/mnt/data Type=ext4 Options= [Install] RequiredBy=teamcity-server.service - name: "get-mysql-connector.service" enable: true content: | [Unit] Before=teamcity-server.service After=mnt-data.mount Requires=mnt-data.mount ConditionPathExists=!/mnt/data/teamcity-server/data/lib/jdbc/mysql-connector-java-bin.jar [Service] Type=oneshot ExecStart=/bin/mkdir -p /mnt/data/teamcity-server/data/lib/jdbc ExecStart=/bin/bash /etc/teamcity/download-file.sh \ https://repo.maven.apache.org/maven2/mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47.jar \ /mnt/data/teamcity-server/data/lib/jdbc/mysql-connector-java-bin.jar [Install] WantedBy=multi-user.target - name: "get-azure-plugins.service" enable: true content: | [Unit] Before=teamcity-server.service After=mnt-data.mount Requires=mnt-data.mount ConditionPathExists=!/mnt/data/teamcity-server/data/plugins/azure-plugins.txt [Service] Type=oneshot ExecStart=/bin/mkdir -p /mnt/data/teamcity-server/data/plugins ExecStart=/bin/bash /etc/teamcity/download-file.sh \ https://raw.githubusercontent.com/JetBrains/teamcity-azure-template/master/azure-plugins.txt \ /mnt/data/teamcity-server/data/plugins/azure-plugins.txt ExecStart=/bin/bash -c 'cd /mnt/data/teamcity-server/data/plugins && curl -K azure-plugins.txt' [Install] WantedBy=multi-user.target - name: "prepare-config.service" enable: true content: | [Unit] Before=teamcity-server.service After=mnt-data.mount Requires=mnt-data.mount network-online.target ConditionPathExists=!/mnt/data/teamcity-server/data/config [Service] Type=oneshot ExecStart=/bin/mkdir -p /mnt/data/teamcity-server/data/config ExecStart=/bin/mv /etc/teamcity/database.properties /mnt/data/teamcity-server/data/config/ ExecStart=/bin/mv /etc/teamcity/disabled-plugins.xml /mnt/data/teamcity-server/data/config/ [Install] WantedBy=multi-user.target - name: "teamcity-update.service" command: "start" content: | [Unit] After=docker.service Before=teamcity-server.service teamcity-agent.service Requires=docker.service network-online.target [Service] ExecStart=/bin/sh /etc/teamcity/update.sh Restart=always [Install] WantedBy=multi-user.target - name: "teamcity-server.service" command: "start" content: | [Unit] Description=TeamCity Server After=docker.service mnt-data.mount get-mysql-connector.service get-azure-plugins.service prepare-config.service teamcity-update.service letsencrypt.service Requires=docker.service mnt-data.mount get-mysql-connector.service get-azure-plugins.service prepare-config.service teamcity-update.service letsencrypt.service [Service] TimeoutStartSec=1200s EnvironmentFile=/etc/teamcity/version EnvironmentFile=/etc/teamcity/hostname ExecStartPre=/bin/sh -c "docker images --filter 'before=jetbrains/teamcity-server:${TEAMCITY_VERSION}' --format '{{.ID}} {{.Repository}}' | grep 'jetbrains/teamcity-server' | grep -Eo '^[^ ]+' | xargs -r docker rmi" ExecStartPre=/usr/bin/docker create \ -e TEAMCITY_SERVER_MEM_OPTS="-Xmx$(($(grep MemTotal /proc/meminfo | awk '{print $2}') / 2))k -XX:MaxPermSize=270m -XX:ReservedCodeCacheSize=350m" \ -e VIRTUAL_PORT=8111 \ -e VIRTUAL_HOST=${DOMAIN_NAME} \ -e LETSENCRYPT_HOST=${DOMAIN_NAME} %DomainOwnerEmailEnv% \ -v /mnt/data/teamcity-server/data:/data/teamcity_server/datadir \ -v /mnt/data/teamcity-server/logs:/opt/teamcity/logs \ -v /mnt/resource/teamcity-server/temp:/opt/teamcity/temp \ --name teamcity-server \ jetbrains/teamcity-server:${TEAMCITY_VERSION} ExecStartPre=/bin/sh -c "echo 'azure' > dist && docker cp dist teamcity-server:/opt/teamcity/webapps/ROOT/WEB-INF/DistributionType.txt && rm dist" ExecStart=/usr/bin/docker start teamcity-server -a ExecStop=-/usr/bin/docker exec teamcity-server /opt/teamcity/bin/teamcity-server.sh stop 60 ExecStopPost=-/usr/bin/docker stop teamcity-server ExecStopPost=-/usr/bin/docker rm teamcity-server Restart=always [Install] WantedBy=multi-user.target - name: "teamcity-agent.service" command: "start" content: | [Unit] Description=TeamCity Agent After=teamcity-server.service teamcity-update.service Requires=docker.service teamcity-server.service teamcity-update.service [Service] TimeoutStartSec=1200s EnvironmentFile=/etc/teamcity/version EnvironmentFile=/etc/teamcity/hostname ExecStartPre=/bin/sh -c "docker images --filter 'before=jetbrains/teamcity-agent:${TEAMCITY_VERSION}' --format '{{.ID}} {{.Repository}}' | grep 'jetbrains/teamcity-agent' | grep -Eo '^[^ ]+' | xargs -r docker rmi" ExecStart=/usr/bin/docker run \ -v /mnt/data/teamcity-agent/conf:/opt/buildagent/conf \ -v /mnt/data/teamcity-agent/logs:/opt/buildagent/logs \ -v /mnt/data/teamcity-agent/plugins:/opt/buildagent/plugins \ -v /mnt/data/teamcity-agent/system:/opt/buildagent/system \ -v /mnt/resource/teamcity-agent/temp:/opt/buildagent/temp \ -v /mnt/resource/teamcity-server/temp:/opt/teamcity/temp \ -v /mnt/data/teamcity-agent/tools:/opt/buildagent/tools \ --privileged \ -e DOCKER_IN_DOCKER=start \ -e SERVER_URL=https://${DOMAIN_NAME} \ -e AGENT_NAME=Default \ --name teamcity-agent \ jetbrains/teamcity-agent:${TEAMCITY_VERSION} ExecStop=-/usr/bin/docker exec teamcity-agent /opt/buildagent/bin/agent.sh stop ExecStopPost=-/usr/bin/docker stop teamcity-agent ExecStopPost=-/usr/bin/docker rm teamcity-agent Restart=always [Install] WantedBy=multi-user.target - name: "nginx.service" command: "start" content: | [Unit] Description=NGINX reverse proxy Requires=docker.service [Service] TimeoutStartSec=1200s ExecStartPre=/bin/mkdir -p /opt/domains/certs ExecStartPre=/bin/mkdir -p /opt/domains/vhost.d ExecStartPre=/bin/mkdir -p /opt/domains/nginx/html ExecStart=/usr/bin/docker run \ -p 80:80 \ -p 443:443 \ -v /opt/domains/certs:/etc/nginx/certs:ro \ -v /opt/domains/vhost.d:/etc/nginx/vhost.d \ -v /opt/domains/nginx/html:/usr/share/nginx/html \ -v /var/run/docker.sock:/tmp/docker.sock:ro \ --name nginx \ jwilder/nginx-proxy ExecStop=-/usr/bin/docker stop nginx ExecStopPost=-/usr/bin/docker rm nginx Restart=always [Install] WantedBy=multi-user.target - name: "letsencrypt.service" command: "start" content: | [Unit] Description=Let's Encrypt Requires=docker.service nginx.service After=nginx.service [Service] TimeoutStartSec=1200s ExecStart=/usr/bin/docker run \ -v /opt/domains/certs:/etc/nginx/certs:rw \ --volumes-from nginx \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ --name letsencrypt \ jrcs/letsencrypt-nginx-proxy-companion ExecStop=-/usr/bin/docker stop letsencrypt ExecStopPost=-/usr/bin/docker rm letsencrypt Restart=always [Install] WantedBy=multi-user.target - name: "report-waiter-status.service" enable: true command: "start" content: | [Unit] Requires=docker.service teamcity-server.service nginx.service letsencrypt.service ConditionPathExists=!/etc/teamcity/waiter [Service] Type=oneshot EnvironmentFile=/etc/teamcity/hostname ExecStartPre=/bin/bash /etc/teamcity/check-certificate.sh ExecStart=/bin/bash -c "until $(curl --output /dev/null --silent --fail https://${DOMAIN_NAME}); do echo 'Waiting for success response from ${DOMAIN_NAME}'; sleep 10; done;" ExecStartPost=/bin/touch /etc/teamcity/waiter [Install] WantedBy=multi-user.target