loader

Here are some useful tips for DevOps teams using AWS CLI on a regular basis.

# restart Apache
$ sudo service httpd restart

# edit vhosts file
$ sudo nano /etc/httpd/conf.d/vhost.conf

# edit httpd.conf file 
$ sudo nano /etc/httpd/conf/httpd.conf

# edit PHP .ini file
$ sudo nano /etc/php.ini

# copy all from one dir to another
$ sudo cp -R /var/www/html/* /var/www/vhosts/staging

# to delete everything within a directory but not the directory itself (including inner sub-directories)
$ sudo rm -rf /var/www/html/*

# the command leaves a .htaccess file behind if there is one there
$ sudo rm -rf /var/www/html/.htaccess 

# staging (if applicable)
$ sudo rm -rf /var/www/vhosts/staging/* 
$ sudo rm -rf /var/www/vhosts/staging/.htaccess

# zip a directory and everything in it
$ sudo zip -r html.zip /var/www/html/*

# aws configure IAM credentials
$ aws configure
AWS Access Key ID [None]: accesskey
AWS Secret Access Key [None]: secretkey
Default region name [None]: eu-west-1
Default output format [None]:

# add/remove securiyt groups entries (example opens port 80 to all)
$ aws ec2 authorize-security-group-ingress --group-id sg-******** --protocol tcp --port 80 --cidr 0.0.0.0/0
$ aws ec2 revoke-security-group-ingress --group-id sg-******** --protocol tcp --port 80 --cidr 0.0.0.0/0

# mysqldb export/dump
$ mysqldump -hyour-host-name --port=3306 -uroot -pyour-password --databases example > /var/www/backup/daily/daily_`date +\%Y-\%m-\%d_\%H-\%M-\%S`.sql

# mysqldb write export/dump
$ mysql -hyour-host-name --port=3306 -uroot -pyour-password example < /var/www/backup/daily/daily_`date +\%Y-\%m-\%d_\%H-\%M-\%S`.sql

# logs - global system messages, including the messages that are logged during system startup. Includes mail, cron, daemon, kern, auth, etc. (use your preferred text editor e.g. Vim, Gedit, Atom)
$ sudo nano /var/log/message 
# logs - Authenication logs
$ sudo nano /var/log/auth
# logs - Kernel logs
$ sudo nano /var/log/kern
# logs - Cron logs
$ sudo nano /var/log/cron
# logs - Access Logs
$ sudo nano /var/log/httpd/access_log
$ crontab -e (not sudo)

# press i to INSERT onto crontab

30 4 * * * aws s3 sync /var/www/backup/ s3://example-backup/ 
0 2 * * * mysqldump -hyour-host-name --port=3306 -uroot -pyour-password --databases example > /var/www/backup/daily/daily_`date +\%Y-\%m-\%d_\%H-\%M-\%S`.sql
45 1 * * * zip -r /var/www/backup/daily/html.zip /var/www/html
10 3 * * * find /var/www/backup/daily* -mtime +2 -exec rm {} \;

1 2 * * 0 mysqldump -hyour-host-name --port=3306 -uroot -pyour-password --databases example > /var/www/backup/weekly/weekly_`date +\%Y-\%m-\%d_\%H-\%M-\%S`.sql
1 2 * * 0 zip -r /var/www/backup/weekly/html.zip /var/www/html
1 3 * * 0 find /var/www/backup/weekly* -mtime +8 -exec rm {} \;

0 1 1 * * mysqldump -hyour-host-name --port=3306 -uroot -pyour-password --databases example> /var/www/backup/monthly/monthly_`date +\%Y-\%m-\%d_\%H-\%M-\%S`.sql
0 1 1 * * zip -r /var/www/backup/monthly/html.zip /var/www/html
0 2 1 * * find /var/www/backup/montly* -mtime +32 -exec rm {} \;

30 5 1 * * /opt/letsencrypt/letsencrypt-auto renew --config /etc/letsencrypt/config.ini --agree-tos 

#run a few days before your SSL registration date each month to be sure its covered

ESC - :wq to save
#change to our home directory
cd

# Download and install the "Extra Packages for Enterprise Linux (EPEL)"
wget -O epel.rpm –nv https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo yum install -y ./epel.rpm

# Install certbot for Apache (part of EPEL)
sudo yum install python2-certbot-apache.noarch

# Create a dummy ssl certificate. This will not become part of your ssl strategy. 
# You only need to install it because of default settings in Apache ssl configuration
sudo /etc/pki/tls/certs/make-dummy-cert localhost.crt
sudo service httpd restart
Now we’re ready to execute certbot to request our SSL certificate.
# Launch the certbot installer with the following parameters:
#     -i apache                     Use the Apache installer.
#     -a manual                     Authenticate domain ownership manually.
#     --preferred-challenges dns    Use DNS TXT records for authentication challenge.
#     -d lamp.example.com           Specify the domain for the SSL/TLS certificate.
sudo certbot -i apache -a manual --preferred-challenges dns -d example.com
$ sudo crontab -e
# add to crontab
39 1,13 * * * root certbot renew --no-self-upgrade
- Select AMI and Launch

- Select IAM Role (or create new)

#!/bin/bash
service httpd start
chkconfig httpd on

- Select Security Group (or create new)

- Select Key Pair (or create new)

# If new Convert key to PPK

- Connect to Workbench

# distinct user for each DB - never use root

- 3rd party App to schedule backups
# Remove current php & apache - removed guide $ so you can copy and paste commands directly into CLI

sudo service httpd stop
sudo yum remove httpd* php* 
# Remove any third party repos that aren't relevant
sudo yum repolist
sudo yum remove remi-safe

# Install Apache24 for Amazon AMI
sudo yum install httpd24

# Download webtatic
mkdir -p /tmp/php7
cd /tmp/php7
wget https://mirror.webtatic.com/yum/el6/latest.rpm

# Install webtatic repo
sudo yum install latest.rpm
sudo vi /etc/yum.repos.d/webtatic.repo - set repo to enabled
sudo yum clean all

# Install php7
sudo yum install --enablerepo=webtatic php73
sudo yum install --enablerepo=webtatic php74
php -v # outputs build data
sudo yum install php73-opcache php73-xml php73-pdo php73-mysqlnd php73-gd php73-pecl-apcu php73-mbstring php73-imap php73-mcrypt php73-intl
sudo yum install php74-opcache php74-xml php74-pdo php74-mysqlnd php74-gd php74-pecl-apcu php74-mbstring php74-imap php74-mcrypt php74-intl
sudo yum install mod24_ssl

# these edits are needed on your php.ini file, values are for demo purposes
post_max_size 25M
upload_max_filesize 10M
max_execution_time 180
max_input_time 180
memory_limit = 25M
short_open_tag = On
1. Create VPC peering: [1]
You will need to create a new VPC to avoid a conflict between the default CIDR block IP's. This will require the creation of new subnets for the new VPC (created automatically with default VPC)

2. Route Tables [2] [3]
a. Source: Update the route table(to which the subnet is associated with your EC2 instance) with the Destination IP address of target and Target as VPC Peering connection(target). 
b. Target: Update the route table(to which the subnet is associated with your RDS instance) with the Destination IP address of source and Target as VPC Peering connection(source).

3. Security Groups [4]
a. Source instance's security group outbound rule is allowing ALL to Anywhere. 
b. Destination RDS security group's inbound rule must allow Port  (1024) from source IP. Add a security rule in the security groups in master account.
A. On an existing instance:
$ sudo yum install ruby
$ sudo yum install wget
$ cd /home/ec2-user
$ wget https://aws-codedeploy-eu-west-1.s3.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto
B. booting new instance (bootstrap user data):
#!/bin/bash
yum -y update
yum install -y ruby
yum install -y aws-cli
cd /home/ec2-user
aws s3 cp s3://aws-codedeploy-us-east-2/latest/install . --region us-east-2
chmod +x ./install
./install auto

Check Status:
$ sudo service codedeploy-agent status

Logs: 
/var/log/aws/codedeploy-agent/codedeploy-agent.log
/opt/codedeploy-agent/deployment-root
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

Here is a complete example including the default WordPress code: 

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE] 

# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# END WordPress
$ aws ec2 stop-instances --instance-ids i-XXXXXXXXXXXXXXXXX --region eu-west-1

$ aws ec2 modify-instance-attribute --instance-id i-XXXXXXXXXXXXXXXXX --region eu-west-1 --ena-support

$ aws ec2 modify-instance-attribute --instance-id i-XXXXXXXXXXXXXXXXX --instance-type "{\"Value\": \"t3.*****\"}"

$ aws ec2 start-instances --instance-ids i-XXXXXXXXXXXXXXXXX --region eu-west-1

# if expanding the size of an EBS volume run the following also
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html
# using your preferred CLI editor
$ sudo nano /etc/httpd/conf/httpd.conf

# Add this to the top of the conf file
$ Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=strict
# install telnet, ncat and openssl (if using SMTP over starttls)
$ sudo yum install telnet
$ sudo yum install nmap-ncat -y
$ sudo yum install openssl

# checking SMTP connection using telnet (this example uses AWS hostnames but use whatever is applicable in your case)
$ telnet email-smtp.us-east-1.amazonaws.com 587
$ telnet email-smtp.us-east-1.amazonaws.com 25
$ telnet email-smtp.us-east-1.amazonaws.com 465

# checking SMTP connection using openssl
$ openssl s_client -connect email-smtp.us-east-1.amazonaws.com:587 -starttls smtp
# To apply a fix via CLI
$ sudo nano /var/www/html/wp-content/plugins/woocommerce/includes/class-wc-data-store.php # and navigate to line number


# insert return false; above the throw exception e.g.:

# was 
if ( ! $order->get_id() || ! ( $post_object = get_post( $order->get_id() ) ) || ! in_array( $post_object->post_type, wc_get_order_types() ) ) { 
			throw new Exception( __( 'Invalid product.', 'woocommerce' ) );			
                     }
# modified 
if ( ! $order->get_id() || ! ( $post_object = get_post( $order->get_id() ) ) || ! in_array( $post_object->post_type, wc_get_order_types() ) ) {
                        return false;
			throw new Exception( __( 'Invalid product.', 'woocommerce' ) );
		}
 # save changes and admin login page will be accessible again 
# To apply a fix via CLI on instance
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
$ . ~/.nvm/nvm.sh
$ nvm install node
$ node -e "console.log('Running Node.js ' + process.version)"
# restart apache
$ sudo /opt/bitnami/ctlscript.sh restart apache

# remove bitnami banner
$ sudo /opt/bitnami/apps/wordpress/bnconfig --disable_banner 1
$ sudo /opt/bitnami/ctlscript.sh restart apache

# ssl configuration
$ sudo /opt/bitnami/bncert-tool

# setting correct owner permissions
$ sudo chown daemon:daemon -R /opt/bitnami/apps/wordpress/htdocs

# for debug to file
$ sudo nano /opt/bitnami/apps/wordpress/htdocs/wp-config.php

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define( 'WP_DEBUG_DISPLAY', false );
$ sudo su root 
$ yum install python27-devel git 
$ git clone 
https://github.com/letsencrypt
/letsencrypt /opt/letsencrypt 
$ /opt/letsencrypt/letsencrypt-auto
--debug 
---- 
#if using an AMI where letsencrypt is already installed you may come across zope.interface issue in which case run these commands 
$ rm -rf ~/.local/share/letsencrypt 
$ rm -rf /opt/eff.org/certbot/ 
$ unset PYTHON_INSTALL_LAYOUT; 
$ rm -rf /root/.local/share/letsencrypt/; 
----- 
$ echo "rsa-key-size = 4096" >> /etc/letsencrypt/config.ini 
$ echo "email = example@example.com" >> /etc/letsencrypt/config.ini 
# the following commands are assuming you have a UAT/Staging version of your site which you want to run over HTTPS also 
$ /opt/letsencrypt/letsencrypt-auto certonly --webroot -w /var/www/vhosts/staging -d uat.example.com --config /etc/letsencrypt/config.ini --agree-tos 
$ /opt/letsencrypt/letsencrypt-auto certonly --webroot -w /var/www/vhosts/staging -d www.uat.example.com --config /etc/letsencrypt/config.ini --agree-tos 
$ /opt/letsencrypt/letsencrypt-auto certonly --webroot -w /var/www/html -d example.com --config /etc/letsencrypt/config.ini --agree-tos 
$ /opt/letsencrypt/letsencrypt-auto certonly --webroot -w /var/www/html -d www.example.com --config /etc/letsencrypt/config.ini --agree-tos 
$ rmdir /var/www/vhosts/staging/.well-known 
$ rmdir /var/www/html/.well-known
# Your certs should now be validated, so here is the VirtualHost settings for your vhosts.conf file 
# Listen 443 
ServerName uat.example.com 
DocumentRoot "/var/www/vhosts/staging" 
SSLEngine on 
SSLCertificateFile /etc/letsencrypt/live/uat.example.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/uat.example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/uat.example.com/chain.pem SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder on 
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS" 
AllowOverride All ServerName example.com 
DocumentRoot "/var/www/html" 
SSLEngine on 
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder on SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS" 
AllowOverride All # www alternative on live ServerName www.example.com 
DocumentRoot "/var/www/html" 
SSLEngine on 
SSLCertificateFile /etc/letsencrypt/live/www.example.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.example.com/chain.pem 
SSLProtocol All -SSLv2 -SSLv3 
SSLHonorCipherOrder on SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS" 
AllowOverride All 
#restart apache and your site should be running over HTTPS. However, if your vhosts file throws up and error related to un-named VirtualHosts, go to your httpd.conf file and un-comment out: NameVirtualHost *:80 and NameVirtualHost *:443 (you may have to add 443). To find the line in nano use CTL + w 
# To renew, run this command 
$ /opt/letsencrypt/letsencrypt-auto renew --config /etc/letsencrypt/config.ini --agree-tos

# if you are using an instance from an AMI you may have previous certs on this instance which need to be removed for renewals 
rm -rf /etc/letsencrypt/live/remove.com 
rm /etc/letsencrypt/renewal/remove.com.conf