adding run number to web dep for naming, thinging imagebuilder may ne… #64
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
name: Aws Deployment Workflow | |
on: | |
push: | |
branches: | |
- main | |
concurrency: | |
group: miles-systems-${{ github.repository }}-${{ github.ref }} | |
cancel-in-progress: true | |
permissions: | |
id-token: write | |
contents: read | |
jobs: | |
miles-systems: | |
runs-on: ubuntu-latest | |
outputs: | |
account_name: ${{ steps.set-vars.outputs.account_name }} | |
account_id: ${{ steps.set-vars.outputs.account_id }} | |
account_oidc_role: ${{ steps.set-vars.outputs.account_oidc_role }} | |
network_account_oidc_role: ${{ steps.set-vars.outputs.network_account_oidc_role }} | |
current_branch: ${{ steps.set-vars.outputs.current_branch }} | |
subnet_identifier: ${{ steps.set-vars.outputs.subnet_identifier }} | |
imageBuilderScriptBuild: ${{ steps.set-vars.outputs.imageBuilderScriptBuild }} | |
imageBuilderScriptValidate: ${{ steps.set-vars.outputs.imageBuilderScriptValidate }} | |
deployUserDataScript: ${{ steps.set-vars.outputs.deployUserDataScript }} | |
deployTrackUserDataScript: ${{ steps.set-vars.outputs.deployTrackUserDataScript }} | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Set account name, ID, and branch | |
id: set-vars | |
env: | |
imageBuilderScriptBuild: | | |
#!/bin/bash | |
set -eEBx | |
dnf upgrade -y | |
mkdir -p /var/aws-deployment | |
groupadd apache | |
useradd apache -g apache -s /usr/bin/zsh | |
echo apache:apache | chpasswd | |
wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm | |
rpm -ihv --nodeps ./epel-release-latest-8.noarch.rpm | |
wget https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm | |
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023 | |
dnf install -y mysql80-community-release-el9-1.noarch.rpm | |
dnf install -y epel-release gcc-c++ make git jq perl-Digest-SHA httpd httpd-tools mod_ssl links pip socat nvme-cli vsftpd expect aws-cli nodejs httpd perl pcre-devel gcc zlib zlib-devel php-pear php-devel libzip libzip-devel re2c bison autoconf make libtool ccache libxml2-devel sqlite-devel php php-{common,pear,cgi,mbstring,curl,gd,mysqlnd,gettext,json,xml,fpm,intl,posix,dom,zip} zsh mysql-community-server inotify-tools ccze | |
OHMYZSH="$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" | |
sudo -u apache sh -c "$OHMYZSH" 2>&1 | |
sh -c "$OHMYZSH" 2>&1 | |
eval $(ssh-agent) | |
mkdir -p /home/apache/.ssh/ | |
cat > /home/apache/.ssh/id_github_pull_key <<EOF | |
${{ secrets.SSH_PULL_KEY }} | |
EOF | |
cat > /home/apache/.ssh/config <<EOF | |
Host github.com | |
IdentityFile /home/apache/.ssh/id_github_pull_key | |
IdentitiesOnly yes | |
EOF | |
chown -R apache:apache /home/apache/ | |
chmod g+rwX /home/apache/ -R | |
sudo -u apache chmod 600 /home/apache/.ssh/id_github_pull_key | |
sudo -u apache chmod 600 /home/apache/.ssh/config | |
sudo -u apache ssh -o StrictHostKeyChecking=no -i /home/apache/.ssh/id_github_pull_key -T [email protected] 2>&1 || true | |
sed -i -e 's/ssm-user:\/bin\/bash/ssm-user:\/usr\/bin\/zsh/g' \ | |
-e 's/apache:\/bin\/bash/apache:\/usr\/bin\/zsh/g' /etc/passwd | |
sed -i -e 's/\/usr\/libexec\/openssh\/sftp-server/internal-sftp/g' \ | |
-e 's/#Banner none/Banner \/etc\/ssh\/sshd-banner/g' \ | |
-e 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config | |
echo -e "\nMatch Group apache\nAllowTcpForwarding yes\nForceCommand internal-sftp" >>/etc/ssh/sshd_config | |
sed -i 's/AllowOverride None/AllowOverride All/g' /etc/httpd/conf/httpd.conf | |
systemctl restart sshd | |
echo "Installing Custom PHP Version --branch (apache_websocket_accept)" | |
dnf install -y libcurl-devel httpd-devel libffi-devel oniguruma-devel readline-devel libsodium-devel libargon2-devel systemd-devel --allowerasing | |
git clone https://github.com/RichardTMiles/php-src.git --depth 1 --single-branch --branch=feature/apache_websocket_accept ~/php-src | |
cd ~/php-src | |
./buildconf | |
# For development | |
# flags that dont work:: --with-gd | |
./configure --enable-fpm --with-openssl --enable-calendar --with-curl --enable-exif \ | |
--with-ffi -enable-mbstring --with-mysqli --enable-pcntl --with-pdo-mysql --with-readline --enable-shmop \ | |
--enable-soap --enable-sockets --with-sodium --with-password-argon2 --with-pear --with-zip --with-apxs2 \ | |
--with-fpm-systemd --with-fpm-selinux --with-zlib --with-config-file-path=/etc/ | |
num_procs=$(nproc) | |
# Calculate the number of jobs, subtracting 1 if num_procs is greater than 1 | |
if [ "$num_procs" -gt 1 ]; then | |
jobs=$((num_procs - 1)) | |
else | |
jobs=$num_procs | |
fi | |
# Run make with the calculated number of jobs | |
make -j "$jobs" | |
./sapi/cli/php -v | |
rm -rf /usr/local/bin/php /usr/bin/php /usr/sbin/php-fpm /sbin/php-fpm | |
cp /root/php-src/sapi/cli/php /usr/local/bin/php | |
cp /root/php-src/sapi/cli/php /usr/bin/php | |
cp /root/php-src/sapi/fpm/php-fpm /usr/local/sbin/php-fpm | |
cp /root/php-src/sapi/fpm/php-fpm /usr/sbin/php-fpm | |
cp /root/php-src/sapi/fpm/php-fpm /sbin/php-fpm | |
cd /tmp/ | |
# The value of post_max_size must be higher than the value of upload_max_filesize | |
# The value of memory_limit must be higher than the value of post_max_size. | |
# memory_limit > post_max_size > upload_max_filesize | |
sed -i -e 's/memory_limit = 128M/memory_limit = 1024M/g' \ | |
-e 's/post_max_size = 8M/post_max_size = 512M/g' \ | |
-e 's/upload_max_filesize = 2M/upload_max_filesize = 512M/g' \ | |
-e 's/max_execution_time = 30/max_execution_time = 300/g' \ | |
-e 's/max_input_time = 60/max_input_time = 1000/g' /etc/php.ini | |
# @link https://unix.stackexchange.com/questions/13751/kernel-inotify-watch-limit-reached/13757#13757?newreg=bff5352630a1447abcaa9a48664ef6a7 | |
# @link https://stackoverflow.com/questions/535768/what-is-a-reasonable-amount-of-inotify-watches-with-linux | |
# @link https://stackoverflow.com/questions/69337154/aws-ec2-terminal-session-terminated-with-plugin-with-name-standard-stream-not-f | |
sudo sysctl fs.inotify.max_user_watches=2147483647 | |
# @note preserved across restarts | |
echo "fs.inotify.max_user_watches=2147483647" >> /etc/sysctl.conf sysctl -p | |
cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.default | |
# PHP-FPM user change | |
# PHP-FPM will also hijack the error log ini if set. | |
# restart with systemctl restart php-fpm | |
sed -i -e 's/user = apache/user = apache/g' \ | |
-e 's/group = apache/group = apache/g' \ | |
-e 's/;listen.owner = nobody/listen.owner = apache/g' \ | |
-e 's/;listen.group = nobody/listen.group = apache/g' \ | |
-e 's/;listen.mode = 0660/listen.mode = 0660/g' \ | |
-e 's/php_admin_value\[error_log\]/;php_admin_value[error_log]/g' \ | |
-e 's/php_admin_flag\[log_errors\]/;php_admin_flag[log_errors]/g' \ | |
-e 's/;catch_workers_output/catch_workers_output/g' \ | |
-e 's/listen.acl_users = apache,nginx/;listen.acl_users = apache,nginx/g' /etc/php-fpm.d/www.conf | |
cp -s /etc/php-fpm.d/www.conf /usr/local/etc/php-fpm.conf | |
rm -f /usr/lib/systemd/system/php-fpm.service | |
cp /root/php-src/sapi/fpm/php-fpm.service /usr/lib/systemd/system/php-fpm.service | |
# @link https://stackoverflow.com/questions/1421478/how-do-i-use-a-new-line-replacement-in-a-bsd-sed | |
sed -i -e 's/ProtectSystem=full/#ProtectSystem=full/g' \ | |
-e 's/ExecStart=/ExecStartPre=\/bin\/mkdir -p \/usr\/local\/var\/log\/ \nExecStart=/g' \ | |
-e 's/ExecStart=/ExecStartPre=\/bin\/mkdir -p \/run\/php-fpm \nExecStart=/g' /usr/lib/systemd/system/php-fpm.service | |
# you can replace this line with your repo cloning process. We do recommend cloning during the ExecStartPre aws_deployment_boot_scripts.service process below | |
echo "Hello World! Aws Deployment Workflow Success!" > /var/www/html/index.html | |
cat > /etc/systemd/system/aws_deployment_boot_scripts.service <<EOF | |
[Unit] | |
Description=Fedora boot script(s) invoked by cloud-init (web.yaml) | |
After=network.target | |
[Service] | |
Type=oneshot | |
KillMode=process | |
User=root | |
ExecStartPre=/bin/chmod -R +x /var/aws-deployment/ | |
ExecStartPre=/bin/ls --color=always -lah /var/aws-deployment/ | |
ExecStartPre=/var/aws-deployment/success.sh 0 | |
ExecStartPre=/usr/bin/rm -rf /var/www/html/ | |
ExecStartPre=/usr/bin/chown -R apache:apache /var/www/ | |
ExecStartPre=/usr/bin/systemctl enable httpd | |
ExecStartPre=/usr/bin/systemctl start httpd | |
ExecStart=/var/aws-deployment/success.sh 0 | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
imageBuilderScriptValidate: | | |
#!/bin/bash | |
echo 'Validating dependencies step #systemctl status httpd' | |
deployTrackUserDataScript: | | |
#!/bin/bash | |
set -eEBx | |
whoami | |
systemctl status --lines=0 aws_deployment_boot_scripts || echo "Exit code: $?" | |
journalctl --since "1min ago" --utc -u aws_deployment_boot_scripts || echo "Exit code: $?" | |
cat /var/log/syslog || echo "Exit code: $?" | |
truncate -s 0 /var/log/syslog || echo "Exit code: $?" | |
exit 0 | |
deployUserDataScript: | | |
Content-Type: multipart/mixed; boundary="//" | |
MIME-Version: 1.0 | |
--// | |
Content-Type: text/cloud-config; charset="us-ascii" | |
MIME-Version: 1.0 | |
Content-Transfer-Encoding: 7bit | |
Content-Disposition: attachment; filename="cloud-config.txt" | |
#cloud-config | |
cloud_final_modules: | |
- [scripts-user, always] | |
--// | |
Content-Type: text/x-shellscript; charset="us-ascii" | |
MIME-Version: 1.0 | |
Content-Transfer-Encoding: 7bit | |
Content-Disposition: attachment; filename="userdata.txt" | |
#!/bin/bash | |
set -eEBx | |
err() { | |
IFS=' ' read line file <<< "$(caller)" | |
echo "Error ($2) on/near line $line in $file" | |
sleep 80 | |
aws autoscaling complete-lifecycle-action --lifecycle-action-result "ABANDON" --instance-id "$EC2_INSTANCE_ID" --lifecycle-hook-name "ready-hook" --auto-scaling-group-name "${AutoScalingGroup}" --region "${EC2_REGION}" | |
/opt/aws/bin/cfn-signal --exit-code $2 --resource ${AutoScalingGroup} --region ${EC2_REGION} --stack ${AWS_STACK_NAME} | |
} | |
trap 'err $LINENO $?' ERR | |
mkdir -p /var/aws-deployment | |
curl -s https://gist.githubusercontent.com/RichardTMiles/145f7a8e85c974ef7c7637a9862a1a74/raw/aws_ec2_metadata_json.php | php > /var/aws-deployment/aws.json | |
EC2_INSTANCE_ID=$(jq -r '.["instance-id"]' /var/aws-deployment/aws.json) | |
EC2_REGION=$(jq -r '.placement.region' /var/aws-deployment/aws.json) | |
AutoScalingGroup=$(aws autoscaling describe-auto-scaling-instances --instance-ids "$EC2_INSTANCE_ID" --query "AutoScalingInstances[0].AutoScalingGroupName" --output text) | |
AWS_STACK_NAME=$(aws cloudformation describe-stack-resources --physical-resource-id "$EC2_INSTANCE_ID" --query "StackResources[0].StackName" --output text) | |
sudo cat > '/var/aws-deployment/success.sh' <<EOF | |
#!/bin/bash | |
set -x | |
if [ "\$1" = "0" ] || [ -z "\$1" ]; then | |
ACTION_RESULT='CONTINUE' | |
EXIT_CODE=0 | |
else | |
ACTION_RESULT='ABANDON' | |
EXIT_CODE=1 | |
fi | |
aws autoscaling complete-lifecycle-action --instance-id "$EC2_INSTANCE_ID" --lifecycle-hook-name "ready-hook" --auto-scaling-group-name "$AutoScalingGroup" --region "$EC2_REGION" --lifecycle-action-result "\$ACTION_RESULT" | |
/opt/aws/bin/cfn-signal --stack "$AWS_STACK_NAME" --resource "AutoScalingGroup" --region "$EC2_REGION" --exit-code "\$EXIT_CODE" | |
exit \$1 | |
EOF | |
chmod +x /var/aws-deployment/success.sh | |
systemctl enable "aws_deployment_boot_scripts" | |
systemctl start "aws_deployment_boot_scripts" | |
--// | |
run: | | |
echo "version=$VERSION" >> $GITHUB_OUTPUT | |
imageBuilderScriptBuild=$(cat << 'EOF1' | |
${{ env.imageBuilderScriptBuild }} | |
EOF1 | |
) | |
imageBuilderScriptValidate=$(cat << 'EOF1' | |
${{ env.imageBuilderScriptValidate }} | |
EOF1 | |
) | |
deployTrackUserDataScript=$(cat << 'EOF1' | |
${{ env.deployTrackUserDataScript }} | |
EOF1 | |
) | |
deployUserDataScript=$(cat << 'EOF1' | |
${{ env.deployUserDataScript }} | |
EOF1 | |
) | |
echo "imageBuilderScriptBuild<<'EOF'"$'\n'"$imageBuilderScriptBuild"$'\n\'EOF\'\n' >> $GITHUB_OUTPUT | |
echo "imageBuilderScriptValidate<<'EOF'"$'\n'"$imageBuilderScriptValidate"$'\n\'EOF\'\n' >> $GITHUB_OUTPUT | |
echo "deployUserDataScript<<'EOF'"$'\n'"$deployUserDataScript"$'\n\'EOF\'\n' >> $GITHUB_OUTPUT | |
echo "deployTrackUserDataScript<<'EOF'"$'\n'"$deployTrackUserDataScript"$'\n\'EOF\'\n' >> $GITHUB_OUTPUT | |
DEFAULT_BRANCH=$(git remote show origin | awk '/HEAD branch/ {print $NF}') | |
CURRENT_BRANCH="${GITHUB_REF#refs/heads/}" | |
echo "current_branch=${CURRENT_BRANCH}" >> $GITHUB_OUTPUT | |
echo "network_account_oidc_role=arn:aws:iam::211125340395:role/GitHubOIDCRole" >> $GITHUB_OUTPUT | |
if [[ "$CURRENT_BRANCH" != "$DEFAULT_BRANCH" ]]; then | |
ACCOUNT_NAME=development | |
ACCOUNT_ID=767398151348 | |
SUBNET_IDENTIFIER=1 | |
ACCOUNT_OIDC_ROLE="arn:aws:iam::767398151348:role/GitHubOIDCRole" | |
else | |
ACCOUNT_NAME=production | |
ACCOUNT_ID=891377212071 | |
SUBNET_IDENTIFIER=0 | |
ACCOUNT_OIDC_ROLE="arn:aws:iam::891377212071:role/GitHubOIDCRole" | |
fi | |
echo "account_name=${ACCOUNT_NAME}" >> $GITHUB_OUTPUT | |
echo "account_id=${ACCOUNT_ID}" >> $GITHUB_OUTPUT | |
echo "subnet_identifier=${SUBNET_IDENTIFIER}" >> $GITHUB_OUTPUT | |
echo "account_oidc_role=${ACCOUNT_OIDC_ROLE}" >> $GITHUB_OUTPUT | |
cat $GITHUB_OUTPUT | |
AmazonWebServicesDeployment: | |
needs: miles-systems | |
uses: ./.github/workflows/aws.yml | |
secrets: inherit | |
with: | |
regions: us-east-1 | |
emailDomain: miles.systems | |
accountName: ${{ needs.miles-systems.outputs.account_name }} | |
subnetIdentifier: ${{ needs.miles-systems.outputs.subnet_identifier }} | |
networkAccountOidcRole: ${{ needs.miles-systems.outputs.network_account_oidc_role }} | |
instanceDeploymentAccountOidcRole: ${{ needs.miles-systems.outputs.account_oidc_role }} | |
environment: ${{ needs.miles-systems.outputs.current_branch }} | |
imageBuilderScriptBuild: ${{ needs.miles-systems.outputs.imageBuilderScriptBuild }} | |
imageBuilderScriptValidate: ${{ needs.miles-systems.outputs.imageBuilderScriptValidate }} | |
imageBuilderInstanceTypes: t3.2xlarge t3.xlarge | |
deployUserDataScript: ${{ needs.miles-systems.outputs.deployUserDataScript }} | |
deployTrackUserDataScript: ${{ needs.miles-systems.outputs.deployTrackUserDataScript }} | |
minimumRunningInstances: 0 | |
desiredInstanceCapacity: 1 | |
maximumRunningInstances: 2 | |
instanceType: t3.micro | |