Created
January 29, 2018 07:41
-
-
Save waltervargas/3961b056058ec8af71766b387e04ec42 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
AWSTemplateFormatVersion: '2010-09-09' | |
Description: Jenkins Bootstrapping Template | |
Metadata: | |
Version: '0.0.1' | |
Stack: 0 | |
AWS::CloudFormation::Interface: | |
ParameterGroups: | |
- Parameters: | |
- StackPrefix | |
Label: | |
default: Tagging | |
- Parameters: | |
- GitUrl | |
- GitBranch | |
- InstanceType | |
- Key | |
- Plugins | |
- Bucket | |
Label: | |
default: Jenkins | |
Mappings: | |
RegionMap: | |
us-west-1: | |
"amazon": "ami-7690240f" | |
Parameters: | |
InstanceType: | |
Description: Instance Type for Jenkins | |
ConstraintDescription: Please provide a valid Amazon EC2 Instance Type | |
Type: String | |
Default: m3.large | |
AllowedValues: | |
- t2.medium | |
- m3.medium | |
- m3.large | |
Key: | |
ConstraintDescription: Please provide a valid Amazon EC2 Key Pair Name | |
Type: AWS::EC2::KeyPair::KeyName | |
Description: Amazon EC2 Key Pair Name | |
Plugins: | |
Default: job-dsl git github workflow-aggregator pipeline-stage-view docker-custom-build-environment jenkins-multijob-plugin ansicolor | |
ConstraintDescription: Please provide a list of valid Jenkins plugins names | |
Type: String | |
Description: Jenkins plugins id (space separator). | |
JenkinsBucket: | |
Type: String | |
Description: Jenkins Backup and Restore S3 Bucket. | |
Restore: | |
Default: false | |
Type: String | |
Description: Restore Jenkins from last backup? | |
AllowedValues: | |
- true | |
- false | |
GitUrl: | |
ConstraintDescription: Please provide a git url. | |
Type: String | |
Description: Git Repository for IAC. | |
GitBranch: | |
Default: master | |
ConstraintDescription: Must be a valid git branch | |
Type: String | |
Description: Git Branch | |
AllowFromCIDR: | |
Type: String | |
Description: Allow access from this ip address | |
ConstraintDescription: Please Provides a valid CIDR Block. | |
Resources: | |
JenkinsS3AccessPolicy: | |
Type: AWS::IAM::ManagedPolicy | |
Properties: | |
Path: !Sub "/${AWS::StackName}/Jenkins/S3AccessPolicy/" | |
PolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- | |
Effect: Allow | |
Action: | |
- s3:* | |
Resource: | |
- !Sub "arn:aws:s3:::${Bucket}/*" | |
- | |
Effect: Deny | |
Action: | |
- s3:Delete* | |
- s3:*Acl* | |
Resource: | |
- !Sub "arn:aws:s3:::${Bucket}" | |
SeedJenkinsInstanceRole: | |
Type: AWS::IAM::Role | |
Properties: | |
Path: !Sub "/${StackPrefix}/JenkinsInstanceRole/" | |
ManagedPolicyArns: | |
- Ref: SeedJenkinsAccessPolicy | |
- Ref: SeedS3AccessPolicy | |
AssumeRolePolicyDocument: | |
Statement: | |
- Action: | |
- sts:AssumeRole | |
Effect: Allow | |
Principal: | |
Service: | |
- ec2.amazonaws.com | |
SeedJenkinsInstanceProfile: | |
Type: AWS::IAM::InstanceProfile | |
Properties: | |
Path: !Sub "/${StackPrefix}/JenkinsInstanceProfile/" | |
Roles: | |
- Ref: SeedJenkinsInstanceRole | |
JenkinsSG: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
Tags: | |
- Value: !Sub ${StackPrefix} | |
Key: Prefix | |
- Value: !Sub ${StackPrefix}-JenkinsSG | |
Key: Name | |
GroupDescription: Jenkins Security Group | |
SecurityGroupIngress: | |
- ToPort: '22' | |
FromPort: '22' | |
IpProtocol: tcp | |
CidrIp: !Sub ${AllowFromIP} | |
- ToPort: '8080' | |
FromPort: '8080' | |
IpProtocol: tcp | |
CidrIp: !Sub ${AllowFromIP} | |
JenkinsSeedLc: | |
Type: AWS::AutoScaling::LaunchConfiguration | |
Properties: | |
ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", amazon] | |
KeyName: | |
Ref: JenkinsKey | |
SecurityGroups: | |
- Ref: JenkinsSG | |
IamInstanceProfile: | |
Ref: SeedJenkinsInstanceProfile | |
InstanceType: | |
Ref: JenkinsInstanceType | |
UserData: | |
Fn::Base64: !Sub | | |
#!/bin/bash | |
# Update route53 record | |
localip=$(curl -fs http://169.254.169.254/latest/meta-data/local-ipv4) | |
echo "$localip jenkins" >> /etc/hosts | |
hostname jenkins | |
yum update -y | |
yum install -y aws-cfn-bootstrap docker jq perl-Test-Simple.noarch perl-YAML.noarch | |
# docker | |
service docker start | |
chkconfig docker on | |
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource JenkinsSeedLc --configsets jenkins --region ${AWS::Region} | |
Metadata: | |
AWS::CloudFormation::Init: | |
configSets: | |
jenkins: | |
- "jenkins_setup" | |
jenkins_setup: | |
files: | |
/etc/yum.repos.d/jenkins.repo: | |
content: | | |
[jenkins] | |
name=Jenkins | |
baseurl=http://pkg.jenkins.io/redhat | |
gpgcheck=1 | |
owner: "root" | |
group: "root" | |
mode: "000644" | |
/tmp/jenkins-security.groovy: | |
content: !Sub | | |
#!groovy | |
import hudson.security.* | |
import jenkins.model.* | |
def instance = Jenkins.getInstance() | |
def JenkinsPass = System.getenv("JenkinsAdminPassword") | |
println "--> Checking if security has been set already" | |
if (!instance.isUseSecurity()) { | |
println "--> creating local user 'admin'" | |
def hudsonRealm = new HudsonPrivateSecurityRealm(false) | |
hudsonRealm.createAccount('${JenkinsAdminUser}', JenkinsPass) | |
instance.setSecurityRealm(hudsonRealm) | |
def strategy = new FullControlOnceLoggedInAuthorizationStrategy() | |
instance.setAuthorizationStrategy(strategy) | |
instance.save() | |
} | |
owner: "root" | |
group: "root" | |
mode: "000744" | |
/tmp/plugins.groovy: | |
content: !Sub | | |
#!groovy | |
import jenkins.model.* | |
import java.util.logging.Logger | |
def log = Logger.getLogger("") | |
def instance = Jenkins.getInstance() | |
def updateCenter = instance.getUpdateCenter() | |
def pluginManager = instance.getPluginManager() | |
def plugins = "${JenkinsPlugins}".split() | |
def plugins_installed = false | |
log.info("" + plugins) | |
updateCenter.updateAllSites() | |
plugins.each { | |
log.info("plugin: " + it) | |
if (!pluginManager.getPlugin(it)) { | |
def plugin = updateCenter.getPlugin(it) | |
if (plugin){ | |
plugin.deploy() | |
plugins_installed = true | |
log.info("Installing plugin " + it) | |
} | |
} | |
} | |
if (plugins_installed){ | |
instance.save() | |
instance.doSafeRestart() | |
} | |
owner: "root" | |
group: "root" | |
mode: "000744" | |
/tmp/aseed-job: | |
content: !Sub | | |
def GIT_URL='${GitUrl}' | |
def GIT_BRANCH='${GitBranch}' | |
def DEVOPS_BUCKET='${JenkinsBackupBucket}' | |
def DEVOPS_BUCKET_DR='${JenkinsBackupBucket}-dr' | |
job('seed-job') { | |
description('Seed Job') | |
parameters { | |
stringParam('GIT_URL', GIT_URL, 'Repo URL') | |
stringParam('GIT_BRANCH', GIT_BRANCH, 'Git Branch') | |
stringParam('DEVOPS_BUCKET', DEVOPS_BUCKET, 'DEVOPS Bucket') | |
stringParam('DEVOPS_BUCKET_DR', DEVOPS_BUCKET_DR, 'Git Branch') | |
} | |
scm { | |
git('\${!GIT_URL}', '\${!GIT_BRANCH}') | |
} | |
triggers { | |
scm('H/15 * * * *') | |
} | |
steps { | |
dsl { | |
external "jenkins-jobs/**/*.groovy" | |
} | |
} | |
} | |
owner: "root" | |
group: "root" | |
mode: "000744" | |
/tmp/disable-script-security-dsl.groovy: | |
content: !Sub | | |
import javaposse.jobdsl.plugin.GlobalJobDslSecurityConfiguration | |
import jenkins.model.GlobalConfiguration | |
import org.kohsuke.stapler.StaplerRequest | |
// current value | |
println GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).useScriptSecurity | |
// change vaue | |
StaplerRequest stapler = null | |
net.sf.json.JSONObject jsonObject = new net.sf.json.JSONObject() | |
//jsonObject.put("useScriptSecurity", false) // it uses has method https://github.com/jenkinsci/job-dsl-plugin/blob/6a70bba91e671ebe72fd682e92e9abea48a2b050/job-dsl-plugin/src/main/groovy/javaposse/jobdsl/plugin/GlobalJobDslSecurityConfiguration.groovy#L21 | |
GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).configure(stapler, jsonObject) | |
// new value | |
println GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).useScriptSecurity | |
/tmp/zz-load-seed-job.groovy: | |
content: !Sub | | |
import javaposse.jobdsl.dsl.DslScriptLoader | |
import javaposse.jobdsl.plugin.JenkinsJobManagement | |
def jobDslScript = new File('/tmp/aseed-job') | |
def workspace = new File('.') | |
def jobManagement = new JenkinsJobManagement(System.out, [:], workspace) | |
new DslScriptLoader(jobManagement).runScript(jobDslScript.text) | |
owner: "root" | |
group: "root" | |
mode: "000744" | |
/tmp/gitconfig: | |
content: | | |
[user] | |
name = Jenkins Master | |
email = jenkins@jenkins | |
owner: "root" | |
group: "root" | |
mode: "000744" | |
commands: | |
command_01: | |
command: | | |
# Update java version required by Jenkins | |
yum remove -y java-1.7.0-openjdk | |
yum install -y java-1.8.0 | |
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key | |
yum -y install jenkins git | |
usermod -a -G jenkins ec2-user | |
usermod -a -G docker jenkins | |
command_02: | |
command: | | |
echo JENKINS_JAVA_OPTIONS=\"-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false\" >> /etc/sysconfig/jenkins | |
# Add jenkins user to sudoers and disable tty | |
echo "jenkins ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers | |
echo "Defaults:%jenkins !requiretty" >> /etc/sudoers | |
echo "Defaults:jenkins !requiretty" >> /etc/sudoers | |
command_03: | |
command: !Sub | | |
echo "export JenkinsAdminPassword=`aws --region ${AWS::Region} ssm get-parameters --name stack.service.vpc-jenkins.JenkinsAdminPassword --with-decryption --output text | cut -f 4 `" >> /etc/sysconfig/jenkins | |
source /etc/sysconfig/jenkins | |
mkdir $JENKINS_HOME/init.groovy.d 2> /dev/null | |
cp -v /tmp/*.groovy $JENKINS_HOME/init.groovy.d/ 2> /dev/null | |
cp /tmp/gitconfig $JENKINS_HOME/.gitconfig | |
chown -R jenkins $JENKINS_HOME/init.groovy.d/ | |
service jenkins start | |
chkconfig jenkins on | |
command_04: | |
command: !Sub | | |
# Generate ssh deployment key | |
source /etc/sysconfig/jenkins | |
instanceid=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) | |
su -c "ssh-keygen -b 1024 -t rsa -N '' -f $JENKINS_HOME/.ssh/id_rsa" jenkins -s /bin/bash | |
pubkey=$(cat $JENKINS_HOME/.ssh/id_rsa.pub) | |
aws ec2 create-tags --resource $instanceid --tags Key=deploykey,Value="$pubkey" --region ${AWS::Region} | |
echo "StrictHostKeyChecking no" >> $JENKINS_HOME/.ssh/config | |
echo "UserKnownHostsFile /dev/null" >> $JENKINS_HOME/.ssh/config | |
command_05: | |
command: !Sub | | |
source /etc/sysconfig/jenkins | |
if [[ ${JenkinsRestore} == true ]]; | |
then | |
devops_bucket_content=`aws s3 ls s3://${JenkinsBackupBucket}/backups/jenkins/` | |
if [[ $devops_bucket_content == "" ]]; | |
then | |
echo "No backups available"; | |
else | |
wget http://localhost:8080/jnlpJars/jenkins-cli.jar -NqO /opt/jenkins-cli.jar | |
aws s3 sync --region ${AWS::Region} s3://${JenkinsBackupBucket}/backups/jenkins/ /var/lib/jenkins/ | |
chown -R jenkins:jenkins /var/lib/jenkins | |
chmod 600 /var/lib/jenkins/.ssh/id_rsa | |
find /var/lib/jenkins/jobs/ -name "last*" -exec rm -rf '{}' \; | |
sleep 10 | |
java -jar /opt/jenkins-cli.jar -s http://localhost:8080 restart --username ${JenkinsAdminUser} --password $JenkinsAdminPassword | |
pubkey=$(cat $JENKINS_HOME/.ssh/id_rsa.pub) | |
instanceid=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) | |
aws ec2 create-tags --resource $instanceid --tags Key=deploykey,Value="$pubkey" --region ${AWS::Region} | |
fi | |
fi | |
## Removing Jenkins admin password from the ENV | |
sed -i 's/^export JenkinsAdminPassword.*$//g' /etc/sysconfig/jenkins | |
JenkinsASG: | |
Type: AWS::AutoScaling::AutoScalingGroup | |
Properties: | |
DesiredCapacity: 1 | |
Tags: | |
- PropagateAtLaunch: 'true' | |
Value: !Sub "${StackPrefix}" | |
Key: StackPrefix | |
- PropagateAtLaunch: 'true' | |
Value: !Sub "${StackPrefix}-jenkins" | |
Key: Name | |
MinSize: 1 | |
MaxSize: 1 | |
LaunchConfigurationName: | |
Ref: JenkinsSeedLc | |
HealthCheckGracePeriod: '600' | |
HealthCheckType: EC2 | |
AvailabilityZones: | |
Fn::GetAZs: "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment