updating chmod #192
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 }} | |
encryptedPayload: ${{ steps.prepare-secrets.outputs.encryptedPayload }} | |
encryptionKey: ${{ steps.prepare-secrets.outputs.encryptionKey }} | |
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 | |
# Ensure SSM Agent is installed and running | |
if ! systemctl is-active --quiet amazon-ssm-agent; then | |
echo "Amazon SSM Agent is not running. Installing..." | |
if ! dnf install -y amazon-ssm-agent; then | |
echo "Failed to install amazon-ssm-agent. Exiting." | |
exit 1 | |
fi | |
fi | |
# Enable the SSM Agent service | |
if ! systemctl enable amazon-ssm-agent; then | |
echo "Failed to enable amazon-ssm-agent service. Exiting." | |
exit 1 | |
fi | |
# Start the SSM Agent service | |
if ! systemctl start amazon-ssm-agent; then | |
echo "Failed to start amazon-ssm-agent service. Exiting." | |
exit 1 | |
fi | |
# Verify the service is active and running | |
if systemctl is-active --quiet amazon-ssm-agent; then | |
echo "Amazon SSM Agent is installed, enabled, and running successfully." | |
else | |
echo "Amazon SSM Agent failed to start. Please check logs for details." | |
exit 1 | |
fi | |
# Create the ssm-user if it doesn't already exist | |
if ! id -u ssm-user > /dev/null 2>&1; then | |
useradd -m -s /bin/bash ssm-user | |
echo "Created ssm-user." | |
# Grant ssm-user sudo privileges without a password | |
echo "# User rules for ssm-user" > /etc/sudoers.d/ssm-agent-users | |
echo "ssm-user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/ssm-agent-users | |
# Ensure proper permissions for the sudoers file | |
chmod 440 /etc/sudoers.d/ssm-agent-users | |
fi | |
if ! getent passwd ssm-user > /dev/null; then | |
echo "Error: ssm-user not created after waiting." | |
exit 1 | |
fi | |
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_INSTALLER="$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" | |
sh -c "$OHMYZSH_INSTALLER" 2>&1 | |
sudo -u ssm-user sh -c "$OHMYZSH_INSTALLER" 2>&1 | |
sudo -u apache sh -c "$OHMYZSH_INSTALLER" 2>&1 | |
bash <(curl -fsSL https://raw.githubusercontent.com/MilesSystems/aws-deployment/refs/heads/main/.github/assets/shell/powerLevel10k.zsh) | |
sed -i -e 's/ssm-user:\/bin\/bash/ssm-user:\/usr\/bin\/zsh/g' \ | |
-e 's/root:\/bin\/bash/root:\/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 | |
cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.og | |
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 | |
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 --utc -u aws_deployment_boot_scripts --since "1min ago" || echo "Exit code: $?" | |
# Define paths | |
LOG_FILE="/var/log/cloud-init-output.log" | |
COPY_FILE="/tmp/cloud-init-output-copy.log" | |
# Ensure the copy exists | |
if [ ! -f "$COPY_FILE" ]; then | |
echo "Creating a copy of the log file..." | |
cp "$LOG_FILE" "$COPY_FILE" | |
echo "Copy created at $COPY_FILE" | |
exit 0 | |
fi | |
# Compare the original log file with the copy | |
echo "Comparing log files for new entries..." | |
diff_output=$(diff "$COPY_FILE" "$LOG_FILE") | |
if [ -n "$diff_output" ]; then | |
echo "New log entries detected:" | |
echo "$diff_output" | |
else | |
echo "No new log entries." | |
fi | |
# Update the copy with the current state of the log file | |
cp "$LOG_FILE" "$COPY_FILE" | |
echo "Updated the copy of the log file at $COPY_FILE." | |
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 | |
#Output log = /var/log/cloud-init-output.log | |
#Script Source = /var/lib/cloud/instance/scripts/userdata.txt | |
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 | |
SCRIPT_URL="https://raw.githubusercontent.com/MilesSystems/aws-deployment/${{ github.sha }}/.github/assets/shell/deployUserDataScript.sh" | |
bash <( curl -fsSL $SCRIPT_URL ) "${{ github.sha }}" "${{ vars.SSH_PULL_KEY }}" | |
--// | |
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 | |
- name: Prepare encrypted secrets payload | |
id: prepare-secrets | |
run: | | |
# Generate a random encryption key if one is not provided | |
if [ -z "${{ secrets.ENCRYPTION_KEY }}" ]; then | |
echo "The 'secrets.ENCRYPTION_KEY' must be set" | |
exit 1 | |
fi | |
# Create the JSON payload | |
payload=$(jq -n \ | |
--arg secret1 "TEST" \ | |
--arg SSH_PULL_KEY "${{ vars.SSH_PULL_KEY }}" \ | |
'{secret1: $secret1, SSH_PULL_KEY: $SSH_PULL_KEY}') | |
# Encrypt the payload. Create a new key using (openssl rand -base64 32) | |
echo "$payload" | openssl enc -aes-256-cbc -a -salt -pbkdf2 -pass pass:${{ secrets.ENCRYPTION_KEY }} > encrypted_payload.txt | |
# Output the encrypted payload as a job output | |
echo "encryptedPayload<<'EOF'"$'\n'"$(cat encrypted_payload.txt)"$'\n\'EOF\'\n' >> $GITHUB_OUTPUT | |
AmazonWebServicesDeployment: | |
needs: miles-systems | |
uses: ./.github/workflows/aws.yml | |
secrets: inherit | |
with: | |
regions: us-east-1 | |
emailDomain: miles.systems | |
deployHeartbeatTimeout: 800 | |
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: 1 | |
desiredInstanceCapacity: 1 | |
maximumRunningInstances: 2 | |
instanceType: t3.micro | |
secretPayloadEncrypted: ${{ needs.miles-systems.outputs.encryptedPayload }} | |