Reddit DevOps
266 subscribers
30.9K links
Reddit DevOps. #devops
Thanks @reddit2telegram and @r_channels
Download Telegram
ID4vdG1wL2pvaW4uY29uZgpkZXNjcmlwdGlvbiAiSm9pbiB0aGUgc2VyZiBjbHVzdGVyIgpzdGFydCBvbiBydW5sZXZlbCBbMjM0NV0Kc3RvcCBvbiBydW5sZXZlbCBbITIzNDVdCnRhc2sKcmVzcGF3bgpzY3JpcHQKICAgIHNsZWVwIDUKICAgIGV4ZWMgL3Vzci9sb2NhbC9iaW4vc2VyZiBqb2luIDEwLjAuMC41CmVuZCBzY3JpcHQKRU9GCnN1ZG8gbXYgL3RtcC9qb2luLmNvbmYgL2V0Yy9pbml0L3NlcmYtam9pbi5jb25mCnN1ZG8gc3RhcnQgc2VyZi1qb2luCgpjYXQgPDxFT0YgPi90bXAvcXVlcnkuY29uZgpkZXNjcmlwdGlvbiAiUXVlcnkgdGhlIHNlcmYgY2x1c3RlciBsb2FkIgpzdGFydCBvbiBydW5sZXZlbCBbMjM0NV0Kc3RvcCBvbiBydW5sZXZlbCBbITIzNDVdCnJlc3Bhd24Kc2NyaXB0CiAgICBlY2hvIGBkYXRlYCBJIGFtICIke0hPU1ROQU1FfTxicj4iID4gL3Zhci93d3cvaW5kZXguaHRtbC4xCiAgICBzZXJmIHF1ZXJ5IC1uby1hY2sgbG9hZCB8IHNlZCAnc3wkfDxicj58JyA+PiAvdmFyL3d3dy9pbmRleC5odG1sLjEKICAgIG12IC92YXIvd3d3L2luZGV4Lmh0bWwuMSAvdmFyL3d3dy9pbmRleC5odG1sCiAgICBzbGVlcCAxMAplbmQgc2NyaXB0CkVPRgpzdWRvIG12IC90bXAvcXVlcnkuY29uZiAvZXRjL2luaXQvc2VyZi1xdWVyeS5jb25mCnN1ZG8gc3RhcnQgc2VyZi1xdWVyeQoKCgoKCg=="
},
"DependsOn": "PublicRouteGlobal"
},

"LoadBalancerIP": {
"Type": "AWS::EC2::EIP",
"Properties": {
"InstanceId": {
"Ref": "LoadBalancer"
},
"Domain": "vpc"
},
"DependsOn": "VPCGateway"
},

"redisasg": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"AvailabilityZones": [{
"Fn::GetAtt": ["PrivateSubnet", "AvailabilityZone"]
}],
"LaunchConfigurationName": {
"Ref": "WebLaunchConfig"
},
"DesiredCapacity": {
"Ref": "redisboxes"
},
"MinSize": {
"Ref": "redisboxes"
},
"MaxSize": {
"Ref": "redisboxes"
},
"VPCZoneIdentifier": [{
"Ref": "PrivateSubnet"
}]
},
"DependsOn": ["NATDevice", "NATIPAddress", "PrivateRouteGlobal"]
},

"RedisboxesConfig": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Properties": {
"ImageId": {
"Fn::FindInMap": ["AWSINSTAMI", {
"Ref": "AWS::Region"
}, "AMI"]
},
"InstanceType": "m1.small",
"SecurityGroups": [{
"Ref": "InstanceSecurityGroup"
}],
"UserData": "IyEvYmluL3NoCgpzZXQgLWUKCiMgSW5zdGFsbCBIQVByb3h5CnN1ZG8gYXB0LWdldCB1cGRhdGUKc3VkbyBhcHQtZ2V0IGluc3RhbGwgLXkgaGFwcm94eQoKIyBDb25maWd1cmUgaXQgaW4gYSBqYW5rIHdheQpjYXQgPDxFT0YgPi90bXAvaGFwcm94eS5jZmcKZ2xvYmFsCiAgICBkYWVtb24KICAgIG1heGNvbm4gMjU2CgpkZWZhdWx0cwogICAgbW9kZSBodHRwCiAgICB0aW1lb3V0IGNvbm5lY3QgNTAwMG1zCiAgICB0aW1lb3V0IGNsaWVudCA1MDAwMG1zCiAgICB0aW1lb3V0IHNlcnZlciA1MDAwMG1zCgpsaXN0ZW4gc3RhdHMKICAgIGJpbmQgKjo5OTk5CiAgICBtb2RlIGh0dHAKICAgIHN0YXRzIGVuYWJsZQogICAgc3RhdHMgdXJpIC8KICAgIHN0YXRzIHJlZnJlc2ggMnMKCmZyb250ZW5kIHJlZGlzCiAgYmluZCAxMjcuMC4wLjE6NTAwMCBuYW1lIHJlZGlzCiAgZGVmYXVsdF9iYWNrZW5kIHJlZGlzX3NlcnZlcnMKICBtYXhjb25uIDEwMjQKCmJhY2tlbmQgcmVkaXNfc2VydmVycwogIGJhbGFuY2Ugcm91bmRyb2JpbgogICNvcHRpb24gdGNwLWNoZWNrCiAgI3RjcC1jaGVjayBjb25uZWN0CiAgI3RjcC1jaGVjayBzZW5kIFBJTkdcclxuCiAgI3RjcC1jaGVjayBleHBlY3Qgc3RyaW5nICtQT05HCiAgI3RjcC1jaGVjayBzZW5kIFFVSVRcclxuCiAgI3RjcC1jaGVjayBleHBlY3Qgc3RyaW5nICtPSwogICNzZXJ2ZXIgcmVkaXNfNzAwMCBsb2NhbGhvc3Q6NzAwMCBjaGVjayBpbnRlciAxcyB3ZWlnaHQgNzcKICAjc2VydmVyIHJlZGlzXzcwMDEgbG9jYWxob3N0OjcwMDEgY2hlY2sgaW50ZXIgMXMgd2VpZ2h0IDMzCkVPRgpzdWRvIG12IC90bXAvaGFwcm94eS5jZmcgL2V0Yy9oYXByb3h5L2hhcHJveHkuY2ZnCgojIEVuYWJsZSBIQVByb3h5CmNhdCA8PEVPRiA+L3RtcC9oYXByb3h5CkVOQUJMRUQ9MQpFT0YKc3VkbyBtdiAvdG1wL2hhcHJveHkgL2V0Yy9kZWZhdWx0L2hhcHJveHkKCiMgU3RhcnQgaXQKc3VkbyAvZXRjL2luaXQuZC9oYXByb3h5IHN0YXJ0CgpleHBvcnQgU0VSRl9ST0xFPSJyZWRpcyIKCgpjYXQgPDxFT0YgPi90bXAvcmVkaXMuY29uZgpiaW5kIDEyNy4wLjAuMQpwcm90ZWN0ZWQtbW9kZSBubwp0aW1lb3V0IDAKdGNwLWtlZXBhbGl2ZSAzMDAKbG9nbGV2ZWwgbm90aWNlIApwaWRmaWxlIC92YXIvcnVuL3JlZGlzXzYzNzkucGlkCkVPRgoKc3VkbyBtdiAvdG1wL3JlZGlzLmNvbmYgL2V0Yy9yZWRpcy9yZWRpcy5jb25mCgpzZXQgLWUKCnN1ZG8gYXB0LWdldCBpbnN0YWxsIC15IHVuemlwCgpjZCAvdG1wCnVudGlsIHdnZXQgLU8gc2VyZi56aXAgaHR0cHM6Ly9kbC5iaW50cmF5LmNvbS9taXRjaGVsbGgvc2VyZi8wLjYuNF9saW51eF9hbWQ2NC56aXA7IGRvCiAgICBzbGVlcCAxCmRvbmUKdW56aXAgc2VyZi56aXAKc3VkbyBtdiBzZXJmIC91c3IvbG9
jYWwvYmluL3NlcmYKCiMgVGhlIG1lbWJlciBqb2luIHNjcmlwdCBpcyBpbnZva2VkIHdoZW4gYSBtZW1iZXIgam9pbnMgdGhlIFNlcmYgY2x1c3Rlci4KIyBPdXIgam9pbiBzY3JpcHQgc2ltcGx5IGFkZHMgdGhlIG5vZGUgdG8gdGhlIGxvYWQgYmFsYW5jZXIuCmNhdCA8PEVPRiA+L3RtcC9qb2luLnNoCmlmIFsgInhcJHtTRVJGX1RBR19ST0xFfSIgIT0gInhsYiIgXTsgdGhlbgogICAgZWNobyAiTm90IGFuIGxiLiBJZ25vcmluZyBtZW1iZXIgam9pbi4iCiAgICBleGl0IDAKZmkKd2hpbGUgcmVhZCBsaW5lOyBkbwogICAgUk9MRT1cYGVjaG8gXCRsaW5lIHwgYXdrICd7cHJpbnQgXFxcJDMgfSdcYAogICAgaWYgWyAieFwke1JPTEV9IiAhPSAieHdlYiIgXTsgdGhlbgogICAgICAgIGNvbnRpbnVlCiAgICBmaQogICAgZWNobyBcJGxpbmUgfCBcXAogICAgICAgIGF3ayAneyBwcmludGYgIiAgICBzZXJ2ZXIgJXMgJXMgY2hlY2tcXG4iLCBcJDEsIFwkMiB9JyA+Pi9ldGMvaGFwcm94eS9oYXByb3h5LmNmZwpkb25lCi9ldGMvaW5pdC5kL2hhcHJveHkgcmVsb2FkCkVPRgpzdWRvIG12IC90bXAvam9pbi5zaCAvdXNyL2xvY2FsL2Jpbi9zZXJmX21lbWJlcl9qb2luLnNoCmNobW9kICt4IC91c3IvbG9jYWwvYmluL3NlcmZfbWVtYmVyX2pvaW4uc2gKCiMgVGhlIG1lbWJlciBsZWF2ZSBzY3JpcHQgaXMgaW52b2tlZCB3aGVuIGEgbWVtYmVyIGxlYXZlcyBvciBmYWlscyBvdXQKIyBvZiB0aGUgc2VyZiBjbHVzdGVyLiBPdXIgc2NyaXB0IHJlbW92ZXMgdGhlIG5vZGUgZnJvbSB0aGUgbG9hZCBiYWxhbmNlci4KY2F0IDw8RU9GID4vdG1wL2xlYXZlLnNoCmlmIFsgInhcJHtTRVJGX1RBR19ST0xFfSIgIT0gInhsYiIgXTsgdGhlbgogICAgZWNobyAiTm90IGFuIGxiLiBJZ25vcmluZyBtZW1iZXIgbGVhdmUiCiAgICBleGl0IDAKZmkKd2hpbGUgcmVhZCBsaW5lOyBkbwogICAgTkFNRT1cYGVjaG8gXCRsaW5lIHwgYXdrICd7cHJpbnQgXFxcJDEgfSdcYAogICAgc2VkIC1pJycgIi9cJHtOQU1FfSAvZCIgL2V0Yy9oYXByb3h5L2hhcHJveHkuY2ZnCmRvbmUKL2V0Yy9pbml0LmQvaGFwcm94eSByZWxvYWQKRU9GCnN1ZG8gbXYgL3RtcC9sZWF2ZS5zaCAvdXNyL2xvY2FsL2Jpbi9zZXJmX21lbWJlcl9sZWZ0LnNoCmNobW9kICt4IC91c3IvbG9jYWwvYmluL3NlcmZfbWVtYmVyX2xlZnQuc2gKCiMgQ29uZmlndXJlIHRoZSBhZ2VudApjYXQgPDxFT0YgPi90bXAvYWdlbnQuY29uZgpkZXNjcmlwdGlvbiAiU2VyZiBhZ2VudCIKc3RhcnQgb24gcnVubGV2ZWwgWzIzNDVdCnN0b3Agb24gcnVubGV2ZWwgWyEyMzQ1XQpleGVjIC91c3IvbG9jYWwvYmluL3NlcmYgYWdlbnQgXFwKICAgIC1ldmVudC1oYW5kbGVyICJtZW1iZXItam9pbj0vdXNyL2xvY2FsL2Jpbi9zZXJmX21lbWJlcl9qb2luLnNoIiBcXAogICAgLWV2ZW50LWhhbmRsZXIgIm1lbWJlci1sZWF2ZSxtZW1iZXItZmFpbGVkPS91c3IvbG9jYWwvYmluL3NlcmZfbWVtYmVyX2xlZnQuc2giIFxcCiAgICAtZXZlbnQtaGFuZGxlciAicXVlcnk6bG9hZD11cHRpbWUiIFxcCiAgICAtdGFnIHJvbGU9JHtTRVJGX1JPTEV9ID4+L3Zhci9sb2cvc2VyZi5sb2cgMj4mMQpFT0YKc3VkbyBtdiAvdG1wL2FnZW50LmNvbmYgL2V0Yy9pbml0L3NlcmYuY29uZgoKIyBTdGFydCB0aGUgYWdlbnQhCnN1ZG8gc3RhcnQgc2VyZgoKIyBJZiB3ZSdyZSB0aGUgd2ViIG5vZGUsIHRoZW4gd2UgbmVlZCB0byBjb25maWd1cmUgdGhlIGpvaW4gcmV0cnkKaWYgWyAieCR7U0VSRl9ST0xFfSIgIT0gInh3ZWIiIF07IHRoZW4KICAgIGV4aXQgMApmaQoKY2F0IDw8RU9GID4vdG1wL2pvaW4uY29uZgpkZXNjcmlwdGlvbiAiSm9pbiB0aGUgc2VyZiBjbHVzdGVyIgpzdGFydCBvbiBydW5sZXZlbCBbMjM0NV0Kc3RvcCBvbiBydW5sZXZlbCBbITIzNDVdCnRhc2sKcmVzcGF3bgpzY3JpcHQKICAgIHNsZWVwIDUKICAgIGV4ZWMgL3Vzci9sb2NhbC9iaW4vc2VyZiBqb2luIDEwLjAuMC41CmVuZCBzY3JpcHQKRU9GCnN1ZG8gbXYgL3RtcC9qb2luLmNvbmYgL2V0Yy9pbml0L3NlcmYtam9pbi5jb25mCnN1ZG8gc3RhcnQgc2VyZi1qb2luCgpjYXQgPDxFT0YgPi90bXAvcXVlcnkuY29uZgpkZXNjcmlwdGlvbiAiUXVlcnkgdGhlIHNlcmYgY2x1c3RlciBsb2FkIgpzdGFydCBvbiBydW5sZXZlbCBbMjM0NV0Kc3RvcCBvbiBydW5sZXZlbCBbITIzNDVdCnJlc3Bhd24Kc2NyaXB0CiAgICBlY2hvIGBkYXRlYCBJIGFtICIke0hPU1ROQU1FfTxicj4iID4gL3Zhci93d3cvaW5kZXguaHRtbC4xCiAgICBzZXJmIHF1ZXJ5IC1uby1hY2sgbG9hZCB8IHNlZCAnc3wkfDxicj58JyA+PiAvdmFyL3d3dy9pbmRleC5odG1sLjEKICAgIG12IC92YXIvd3d3L2luZGV4Lmh0bWwuMSAvdmFyL3d3dy9pbmRleC5odG1sCiAgICBzbGVlcCAxMAplbmQgc2NyaXB0CkVPRgpzdWRvIG12IC90bXAvcXVlcnkuY29uZiAvZXRjL2luaXQvc2VyZi1xdWVyeS5jb25mCnN1ZG8gc3RhcnQgc2VyZi1xdWVyeQo="

}
},

"InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Serf demo security group",
"VpcId": {
"Ref": "VPC"
},
"SecurityGroupIngress": [{
"IpProtocol": "icmp",
"FromPort": "-1",
"ToPort": "-1",
"CidrIp": "0.0.0.0/0"
}, {
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "0.0.0.0/0"
}, {
"IpProtocol": "tcp",
"FromPort": "6379",
"ToPort": "6379",
"CidrIp": "0.0.0.0/0"
}, {
"IpProtocol": "tcp",
"FromPort": "7946",
"ToPort": "7946",
"CidrIp": "0.0.0.0/0"
}, {
"IpProtocol": "tcp",
"FromPort": "7373",
"ToPort": "7373",
"CidrIp": "0.0.0.0/0"
}]
}
},

"InstanceSecurityGroupec2": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "ec2 jump security grp",
"VpcId": {
"Ref": "VPC"
},
"SecurityGroupIngress": [{
"IpProtocol": "icmp",
"FromPort": "-1",
"ToPort": "-1",
"CidrIp": "0.0.0.0/0"
}, {
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "0.0.0.0/0"
}],
"SecurityGroupEgress": {
"IpProtocol": "tcp",
"FromPort": "-1",
"ToPort": "-1",
"CidrIp": "0.0.0.0/0"
}
}
},

"ec2Server": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-123456",
"InstanceType": {
"Ref": "InstanceType"
},
"SecurityGroupIds": [{
"Ref": "InstanceSecurityGroupec2"
}],
"SubnetId": {
"Ref": "PublicSubnet"
},
},
}

"InstanceSecurityGroupSelfRule": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Ref": "InstanceSecurityGroup"
},
"IpProtocol": "-1",
"FromPort": "0",
"ToPort": "65535",
"SourceSecurityGroupId": {
"Ref": "InstanceSecurityGroup"
}
}
}
}
}

lbuserdata.sh

#!/bin/sh

set -e

# Install HAProxy
sudo apt-get update
sudo apt-get install -y haproxy

# Configure it in a jank way
cat <<EOF >/tmp/haproxy.cfg
global
daemon
maxconn 256

defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms

listen stats
bind *:9999
mode http
stats enable
stats uri /
stats refresh 2s

#listen http-in
# bind *:80
# balance roundrobin
# option http-server-close

frontend redis
bind 127.0.0.1:5000 name redis
default_backend redis_servers
maxconn 1024

backend redis_servers
balance roundrobin
#option tcp-check
#tcp-check connect
#tcp-check send PING\r\n
#tcp-check expect string +PONG
#tcp-check send QUIT\r\n
#tcp-check expect string +OK
#server redis_7000 localhost:7000 check inter 1s weight 77
#server redis_7001 localhost:7001 check inter 1s weight 33

EOF
sudo mv /tmp/haproxy.cfg /etc/haproxy/haproxy.cfg

# Enable HAProxy
cat <<EOF >/tmp/haproxy
ENABLED=1
EOF
sudo mv /tmp/haproxy /etc/default/haproxy

# Start it
sudo /etc/init.d/haproxy start

export SERF_ROLE="lb"


set -e

sudo apt-get install -y unzip

cd /tmp
until wget -O serf.zip https://dl.bintray.com/mitchellh/serf/0.6.4_linux_amd64.zip; do
sleep 1
done
unzip serf.zip
sudo mv serf /usr/local/bin/serf

# The member join script is invoked when a member joins the Serf cluster.
# Our join script simply adds the node to the load balancer.
cat <<EOF >/tmp/join.sh
if [ "x\${SERF_TAG_ROLE}" != "xlb" ]; then
echo "Not an lb. Ignoring member join."
exit 0
fi
while read line; do
ROLE=\`echo \$line | awk '{print \\\$3 }'\`
if [ "x\${ROLE}" != "xweb" ]; then
continue
fi
echo \$line | \\
awk '{ printf " server %s %s check\\n", \$1, \$2 }' >>/etc/haproxy/haproxy.cfg
done
/etc/init.d/haproxy reload
EOF
sudo mv /tmp/join.sh /usr/local/bin/serf_member_join.sh
chmod +x /usr/local/bin/serf_member_join.sh

# The member leave script is invoked when a member leaves or fails out
# of the serf cluster. Our script removes the node from the load balancer.
cat <<EOF >/tmp/leav
e.sh
if [ "x\${SERF_TAG_ROLE}" != "xlb" ]; then
echo "Not an lb. Ignoring member leave"
exit 0
fi
while read line; do
NAME=\`echo \$line | awk '{print \\\$1 }'\`
sed -i'' "/\${NAME} /d" /etc/haproxy/haproxy.cfg
done
/etc/init.d/haproxy reload
EOF
sudo mv /tmp/leave.sh /usr/local/bin/serf_member_left.sh
chmod +x /usr/local/bin/serf_member_left.sh

# Configure the agent
cat <<EOF >/tmp/agent.conf
description "Serf agent"
start on runlevel [2345]
stop on runlevel [!2345]
exec /usr/local/bin/serf agent \\
-event-handler "member-join=/usr/local/bin/serf_member_join.sh" \\
-event-handler "member-leave,member-failed=/usr/local/bin/serf_member_left.sh" \\
-event-handler "query:load=uptime" \\
-tag role=${SERF_ROLE} >>/var/log/serf.log 2>&1
EOF
sudo mv /tmp/agent.conf /etc/init/serf.conf

# Start the agent!
sudo start serf

# If we're the web node, then we need to configure the join retry
if [ "x${SERF_ROLE}" != "xweb" ]; then
exit 0
fi

cat <<EOF >/tmp/join.conf
description "Join the serf cluster"
start on runlevel [2345]
stop on runlevel [!2345]
task
respawn
script
sleep 5
exec /usr/local/bin/serf join 10.0.0.5
end script
EOF
sudo mv /tmp/join.conf /etc/init/serf-join.conf
sudo start serf-join

cat <<EOF >/tmp/query.conf
description "Query the serf cluster load"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
script
echo `date` I am "${HOSTNAME}<br>" > /var/www/index.html.1
serf query -no-ack load | sed 's|$|<br>|' >> /var/www/index.html.1
mv /var/www/index.html.1 /var/www/index.html
sleep 10
end script
EOF
sudo mv /tmp/query.conf /etc/init/serf-query.conf
sudo start serf-query

redisboxdata.sh
#!/bin/sh

set -e

# Install HAProxy
sudo apt-get update
sudo apt-get install -y haproxy

# Configure it in a jank way
cat <<EOF >/tmp/haproxy.cfg
global
daemon
maxconn 256

defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms

listen stats
bind *:9999
mode http
stats enable
stats uri /
stats refresh 2s

frontend redis
bind 127.0.0.1:5000 name redis
default_backend redis_servers
maxconn 1024

backend redis_servers
balance roundrobin
#option tcp-check
#tcp-check connect
#tcp-check send PING\r\n
#tcp-check expect string +PONG
#tcp-check send QUIT\r\n
#tcp-check expect string +OK
#server redis_7000 localhost:7000 check inter 1s weight 77
#server redis_7001 localhost:7001 check inter 1s weight 33
EOF
sudo mv /tmp/haproxy.cfg /etc/haproxy/haproxy.cfg

# Enable HAProxy
cat <<EOF >/tmp/haproxy
ENABLED=1
EOF
sudo mv /tmp/haproxy /etc/default/haproxy

# Start it
sudo /etc/init.d/haproxy start

export SERF_ROLE="redis"


cat <<EOF >/tmp/redis.conf
bind 127.0.0.1
protected-mode no
timeout 0
tcp-keepalive 300
loglevel notice
pidfile /var/run/redis_6379.pid
EOF

sudo mv /tmp/redis.conf /etc/redis/redis.conf

set -e

sudo apt-get install -y unzip

cd /tmp
until wget -O serf.zip https://dl.bintray.com/mitchellh/serf/0.6.4_linux_amd64.zip; do
sleep 1
done
unzip serf.zip
sudo mv serf /usr/local/bin/serf

# The member join script is invoked when a member joins the Serf cluster.
# Our join script simply adds the node to the load balancer.
cat <<EOF >/tmp/join.sh
if [ "x\${SERF_TAG_ROLE}" != "xlb" ]; then
echo "Not an lb. Ignoring member join."
exit 0
fi
while read line; do
ROLE=\`echo \$line | awk '{print \\\$3 }'\`
if [ "x\${ROLE}" != "xweb" ]; then
con
tinue
fi
echo \$line | \\
awk '{ printf " server %s %s check\\n", \$1, \$2 }' >>/etc/haproxy/haproxy.cfg
done
/etc/init.d/haproxy reload
EOF
sudo mv /tmp/join.sh /usr/local/bin/serf_member_join.sh
chmod +x /usr/local/bin/serf_member_join.sh

# The member leave script is invoked when a member leaves or fails out
# of the serf cluster. Our script removes the node from the load balancer.
cat <<EOF >/tmp/leave.sh
if [ "x\${SERF_TAG_ROLE}" != "xlb" ]; then
echo "Not an lb. Ignoring member leave"
exit 0
fi
while read line; do
NAME=\`echo \$line | awk '{print \\\$1 }'\`
sed -i'' "/\${NAME} /d" /etc/haproxy/haproxy.cfg
done
/etc/init.d/haproxy reload
EOF
sudo mv /tmp/leave.sh /usr/local/bin/serf_member_left.sh
chmod +x /usr/local/bin/serf_member_left.sh

# Configure the agent
cat <<EOF >/tmp/agent.conf
description "Serf agent"
start on runlevel [2345]
stop on runlevel [!2345]
exec /usr/local/bin/serf agent \\
-event-handler "member-join=/usr/local/bin/serf_member_join.sh" \\
-event-handler "member-leave,member-failed=/usr/local/bin/serf_member_left.sh" \\
-event-handler "query:load=uptime" \\
-tag role=${SERF_ROLE} >>/var/log/serf.log 2>&1
EOF
sudo mv /tmp/agent.conf /etc/init/serf.conf

# Start the agent!
sudo start serf

# If we're the web node, then we need to configure the join retry
if [ "x${SERF_ROLE}" != "xweb" ]; then
exit 0
fi

cat <<EOF >/tmp/join.conf
description "Join the serf cluster"
start on runlevel [2345]
stop on runlevel [!2345]
task
respawn
script
sleep 5
exec /usr/local/bin/serf join 10.0.0.5
end script
EOF
sudo mv /tmp/join.conf /etc/init/serf-join.conf
sudo start serf-join

cat <<EOF >/tmp/query.conf
description "Query the serf cluster load"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
script
echo `date` I am "${HOSTNAME}<br>" > /var/www/index.html.1
serf query -no-ack load | sed 's|$|<br>|' >> /var/www/index.html.1
mv /var/www/index.html.1 /var/www/index.html
sleep 10
end script
EOF
sudo mv /tmp/query.conf /etc/init/serf-query.conf
sudo start serf-query

Hello, I m new to this. I have written this which generates

\--vps

\--private/public subnet

\--asg(with starup script)

\--elb

\--separate ec2 instance as a jumpbox to access the redis instacnes in a round robin manner

&#x200B;

getting the following error:

error: Parse error on line 321:

...icSubnet" }, }, } "InstanceS
---------------------^
Expecting 'STRING', got '}'

Also it would be a great help if someone told me if i m on the right track.

https://redd.it/fce9pm
@r_devops
Security Engineer for Small vs Large Company?



Hello all im currently a security engineer for a small company, im responsible for many things like, SIEM tool, Monitoring tools, Identity management, CI/CD pipeline, cloud infrastructure, kubernetes clusters, etc etc. Basically a Cloud Security Engineer + DevOps, Because we are small company (250) and im the only one on this role i get a a bit of respect and people look up to me, i feel important many times. I get perks like training (SANS included) once a year, they will pay for any certification exam fee, as many as i take during the year, including some cheap training. I been with this company for about 1.5 years, and i just got my first raise few months ago, i was hoping it to be way larger than it was but it was only 4% increase. So i updated LinkedIn and recruiters had a new target :)

That being said i currently got offers too two large companies, one with 700k employees and the other with over 50k employees. Both offers are about 30% than what im currently making, with potential higher bonus, better benefits, but i will go from being a key member that have a say and do on the entire organization to a member of a large team. Which could be a bad thing, or a really good thing since i will have other members to learn from, and to share ideas with.

Note: I did talk to my CIO about not being happy about the salary raise, he told me to eat dirt (on a nice way).

https://redd.it/fcnecx
@r_devops
Does anyone use Bamboo? Where are you now?

I'm stuck using this. This product is barely in a supported mode and so misaligned to the industry of building or deploying software. There's no new features, and the existing ones are half baked, along with price increases and Atlassian's push on Cloud it doesn't make any sense to continue using this.


Where have you gone from Bamboo?


I'm thinking just move to Github Enterprise + Actions/Runners. Security is a big part. Any insights folks?

https://redd.it/fcj9l1
@r_devops
Jenkins multi branch pipeline build PR and branches

So we have a multibranch pipeline. The problem with that is this.

Let\`s say we have a branch **develop** which contains a Jenkinsfile. There is also a webhook which triggers builds if there is a new commit to this branch. If i checkout a new branch (A) from **develop**, Jenkinks tracks and builds that branch. So far so good..

But if i create a PR from branch **A** to **develop**, Jenkins again tracks this PR and builds it.

So now the problem:

If i commit something to branch A, two builds are started.

1. One for branch **A**
2. One for the **PR**

But generally this builds the same code twice! How can a build only the PR if it is created and if not the branch ? I\`m using groovy pipeline.

Thanks in advance :)

https://redd.it/fckakm
@r_devops
Splitting up a monolithic teamcity server. Should i stick to TC or adopt other tools for mostly boilerplate windows builds?

everything we're doing is pretty basic, boilerplate. I've only ever used TC for building windows apps (we also have a jenkins instance that's equally as monolithic, but that's a whole other thing), but i've poked around with gitlab and azure devops in the past for research.

wondering if there's an alternative to TC that's low effort to entry and that won't break the bank?

https://redd.it/fcv4v2
@r_devops
How to add date to custom index via fluentd ?

First, just to give some insight about the architecture:

- There are several microservices running in Kubernetes, and two teams manage those services.
- There is a single elasticsearch cluster on which all the logs from Kubernetes are pushed through `fluentd` Daemon.
- Both teams have different index names (for example, logstash-team1, logstash-team2)

Our logback configuration:

```
<appender name="STDOUT_JSON" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<contextName>
<fieldName>app</fieldName>
</contextName>
<timestamp>
<fieldName>timestamp</fieldName>
<timeZone>UTC</timeZone>
</timestamp>
<loggerName>
<fieldName>logger</fieldName>
</loggerName>
<logLevel>
<fieldName>level</fieldName>
</logLevel>
<callerData>
<classFieldName>class</classFieldName>
<methodFieldName>method</methodFieldName>
<lineFieldName>line</lineFieldName>
<fileFieldName>file</fileFieldName>
</callerData>
<threadName>
<fieldName>thread</fieldName>
</threadName>
<mdc />
<arguments>
<includeNonStructuredArguments>false</includeNonStructuredArguments>
</arguments>
<stackTrace>
<fieldName>stack</fieldName>
</stackTrace>
<message>
<fieldName>message</fieldName>
</message>
</providers>
<customFields>{"esindex": "logstash-team1"}</customFields>
</encoder>
</appender>
```

- Everything works fine with this, however the logs on Kibana are not deleted after 30 days. We figured that if we add date in the `esindex` field, it might solve the problem (there maybe other solutions too, that I'm not aware of).
- So the `esindex` should look something like this: `logstash-team1-%d{yyyy-mm-dd}`.

Is there a way to do this?
Or is there a way to delete logs, after 30 days, without appending date in index name?

https://redd.it/fcwk3k
@r_devops
This Week in DevOps

This weeks newsletter is out and as always I'd love to get some feedback on the style, format and content. Did you find it useful? Is there anything else you'd like to see covered? Any other suggestions?

Ideally I'd like this to be a community shaped newsletter offering maximum value for the least time investment possible. We all have too much to keep up with these days anyway, and I don't want this to be one more thing. Instead I'd like to replace the other sources you currently use to keep up to date on the cloud and give you one clear concise source that covers everything.

Have a look at this weeks edition and let me know what I can do to improve.

[https://thisweekindevops.com/2020/03/03/weekly-roundup-march-2nd-2020/](https://thisweekindevops.com/2020/03/03/weekly-roundup-march-2nd-2020/)

https://redd.it/fcxb6t
@r_devops
Basic way to setup Node/Express/MySQL from one liner CLI on EC2

So I have a backend written in as per the tittle. One main concern is usually it's like "alright please install MySQL and create a user with full privileges" then run this seed file that will generate the database/all the tables.

So I'm looking for a way to get all that running(install Node, run npm install, install MySQL, run seeder)

I've been doing these manually but trying to setup something so I can leave this thing for other developers who may not know how to setup MySQL.

Side note: I currently use systemd to run the node app and it handles cers within my index.js regarding the https part.

I'm also aware some IAMs have specific stacks. But I am just looking at a little Ubuntu server.

Any info is appreciated

https://redd.it/fcw7bi
@r_devops
How to create an on-call schedule that doesn’t suck.

Here's a post on how to create an effective on-call schedule for small startup teams, to the ones that span across multiple teams in multiple timezones and flexible rotations at an enterprise.

[https://blog.fyipe.com/how-to-create-an-on-call-schedule-that-doesnt-suck/](https://blog.fyipe.com/how-to-create-an-on-call-schedule-that-doesnt-suck/)

https://redd.it/fcx4z7
@r_devops
Static Code Analysis in R

Hello Fellow members, I am using RStudio-1.2.5033 and R version 3.3.2 (2016-10-31). I am looking for a tool or a package that does static analysis of ".R" files . I was wondering whether there is a package like there is pylint, pyflakes etc. for python.

I did my research on this and found a Package called ' CodeDepends' but that doesn't support version-3.3.2 and found another one called 'codetools'. Right now I am looking at the 'codetools' package and seeing how that works with a ".r" file.

I am referring to this link:

[https://stat.ethz.ch/R-manual/R-patched/library/codetools/html/00Index.html](https://stat.ethz.ch/R-manual/R-patched/library/codetools/html/00Index.html)

https://redd.it/fcrsap
@r_devops
PoP: Concurrency vs Parallelism in Systems Design

Episode 85 of the Practical Operations Podcast is out! In this episode we focus on Concurrency versus Parallelism and how this affects systems and infrastructure design. Of course, its hard not to make comparisons to our favorite programming languages as well. Listen to our latest episode and tell us what you think!

[https://operations.fm/episodes/85/](https://operations.fm/episodes/85/)

Also available in [iTunes](https://podcasts.apple.com/us/podcast/episode-85-concurrency-vs-parallelism-in-systems-design/id1071645001?i=1000467050735) and [Google Play](https://podcasts.google.com/?feed=aHR0cDovL29wZXJhdGlvbnMuZm0vZXBpc29kZXMvaW5kZXgueG1s&episode=aHR0cDovL2F1ZGlvLm9wZXJhdGlvbnMuZm0vZXBpc29kZS04NS1wYXJhbGxlbC12cy1jb25jdXJyZW50Lm1wMw&ved=0CAYQkfYCahcKEwiQ94vSuf_nAhUAAAAAHQAAAAAQBQ)!

https://redd.it/fd3lq4
@r_devops
Troubleshooting JFrog Artifactory...

Hi there,

First time posting and too be completely honest, a little out of my comfort zone. I am currently looking into a potential issue surrounding Artifactory that was recently set up for our new Docker instance. The team responsible for it had an issue today that they brought to my attention where they are receiving 400 Bad Requests trying to connect to our local Artifactory server from the Docker command line. However, if we open a browser to go to the web portal, they can log in no problem!

One issue I helped solve was there we needed to set up a \*.server.domain.com DNS A record which set up the sub folder in the parent DNS zone ([domain.com](https://domain.com)). This resolved one issue which was surrounding NGinx/Artifactory for mapping through NGinx to the Artifactory api. But now there maybe seems to be another issue where from Docker cmd they still cannot push to Artifactory?

Would this need a cert setup/installed somewhere? On the server running Docker? On the Artifactory server? Or not at all? Thanks!

https://redd.it/fd3awn
@r_devops
How do you handle development data?

I've been thinking about how to set up test data for development, but haven't found an easy way to get data that has the following properties:


* It's sufficiently similar to production that it's useful for testing. I.e. covers a variety of cases and is up to date with the latest schema.
* It's sufficiently different from production that it:
* isn't a security risk (it's anonymized and whatever)
* isn't gigantic (it's a subset of the production data, or it's mock data)

Is this difficult for you all? How do you deal with development data?

https://redd.it/fd4pl1
@r_devops
Building an onboarding series for new technical hires

I’m starting a new project unlike one most discuss in /r/devops and one I haven’t seen done before: a technical onboarding series for new software developer and engineering talent!

Though the details will differ company to company, but it feels like the overall flow shouldn’t be. At my current company, we have applications that live on-premise within corporate data centers with others in the cloud. Both have some underlying technology prerequisites (Kubernetes, AWS) and should probably have various exercises to go along with them followed by building a simple, first-class application.

The problem is that these are purely my ideas without any concrete examples that others do. I hope someone could point me to good examples to model such a process from.

Regards!

https://redd.it/fd4en0
@r_devops
Cloud Engineer vs Devops Engineer

I was curious on the communities take on which role I should focus my attention on when looking in the job market.

&#x200B;

I'm interested in building out cloud resources using IaC, automating processes with python/golang/powershell, deploying CI/CD pipelines and using more Docker/Kubernetes.

&#x200B;

(I understand devops engineer is a catch-all job title but nonetheless)

From what I've been seeing, Devops Engineer roles tend to be focused around building CI/CD pipelines for other teams (primarily devs) using IaC, etc built/maintained by a cloud engineering role.

It seems that Devops is "one layer up the stack" not really needing to focus on how infrastructure is deployed, but mainly on getting it deployed for their pipelines.

&#x200B;

I just want to make sure I choose a role that is furthering my career in the right direction.

https://redd.it/fd639k
@r_devops
Using Packer to share encrypted AMI to multiple accounts

Hello all,

Would anyone know how I would be able to share an encrypted ami that I create in our Dev AWS account to our Staging and Prod AWS accounts using Packer? Looks like there is multiple ways to do it, but ideally I would like to use just one json file to do the entire share as opposed to my other way which would have been:

\- 3 Packer files

\- 1 creates in Dev unencrypted and share to Stg/Prod

\-1 uses that shared ami in Stg to then encrypt it

\-1 uses that shared ami in Prod to then encrypt it

&#x200B;

Would be best if I could just create one encrypted AMI in Dev and share it accordingly

https://redd.it/fd52c2
@r_devops