Skip to content

image builder

image builder #2

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
mkdir -p /var/aws-deployment
dnf install -y aws-cli httpd php php-mysqlnd php-mbstring php-xml
cat > /var/aws-deployment/wait.sh <<'EOF'
while [ ! -f "/var/aws-deployment/success.sh" ]; do
echo "File not found, waiting for 30 seconds..."
sleep 30
done
EOF
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/
ExecStart=/var/aws-deployment/success.sh 0
[Install]
WantedBy=multi-user.target
EOF
imageBuilderScriptValidate: |
#!/bin/bash
echo 'Validating dependencies step #systemctl status httpd'
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"
--//
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
run: |
echo "version=$VERSION" >> $GITHUB_OUTPUT
imageBuilderScriptBuild=$(cat << 'EOF1'
${{ env.imageBuilderScriptBuild }}
EOF1
)
imageBuilderScriptValidate=$(cat << 'EOF1'
${{ env.imageBuilderScriptValidate }}
EOF1
)
deployUserDataScript=$(cat << 'EOF1'
${{ env.deployUserDataScript }}
EOF1
)
deployTrackUserDataScript=$(cat << 'EOF1'
${{ env.deployTrackUserDataScript }}
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
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 }}
deployUserDataScript: ${{ needs.miles-systems.outputs.deployUserDataScript }}
deployTrackUserDataScript: ${{ needs.miles-systems.outputs.deployTrackUserDataScript }}
minimumRunningInstances: 0
desiredInstanceCapacity: 1
maximumRunningInstances: 2