# How-to

## Find all the aws region

```
$ aws ec2 describe-regions --output text --query Regions[].RegionName \
      |tr -s '\t' '\n'
```

## Create EC2 keypair

The keypair is used to connect to the ec2 instance. For more info, [Amazon EC2 Key Pairs and Linux instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)

{% tabs %}
{% tab title="Using CLI" %}
* Go to the user's home directory (`cd ~`)
* Create the key pair

```
$ aws ec2 create-key-pair --key-name MyKeyPair \
    --query "KeyMaterial" \
    --region us-west-2 \
    --output text > MyKeyPair.pem
$ chmod 400 MyKeyPair.pem
```

{% hint style="info" %}
* the region is specified explicitly here, otherwise the configured default region of the `aws cli`  will be used
* when running in the Windows WSL, make sure to _**not create**_ the keypair on the "mount drive"; otherwise `chmod 400` will not change the permission
* the _public key_ of the generated keypair is stored on the aws account in the specified region, with the given `key-name`. Go to: aws console > EC2 > > Network & Security > Key Pairs
* The downloaded `MyKeyPair.pem` contains both the public and private keys.
* The public key can be extract from the `MyKeyPair.pem` file as shown below. For example, to upload the public key to a different region.
{% endhint %}

* Extract the the public key from the `MyKeyPair.pem` file:

```
$ ssh-keygen -y -f ./MyKeyPair.pem > MyKeyPair.pub

# the content should look like
ssh-rsa AAAAB3...
```

* Upload the public key to a selected region:

```
$ aws ec2 import-key-pair --region us-west-1 --key-name MyKeyPair \
      --public-key-material file://MyKeyPair.pub
```

* WARNING: always keep the `MyKeyPair.pem` file securely
{% endtab %}
{% endtabs %}

## Setup ssh agent forwarding

SSH agent forwarding allows you to use your private SSH key that resides on the local host, on the remote host that enables you to ssh from the remote host to another remote host, without having to copy the key to the first remote host. SSH agent forwarding solves many issues including: don't need to copy the ssh key to the remote host, leaving the private key on the host that you don't have full control of; and don't need to install a file transfer software.

* First, setup **ssh forwarding**, If not already, start the `ssh agent`. See [Generating a new SSH key and adding it to the ssh-agent](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) for detailed discussions.

```
$ eval "$(ssh-agent -s)"
Agent pid 2410
```

* Add the ssh key to the agent:

```
$ ssh-add /home/<user>/MyKeyPair.pem
Identity added: /home/<user>/MyKeyPair.pem (/home/<user>/MyKeyPair.pem)
```

* ssh into the remote using the `-A` option:

```
$ ssh -A ec2-user@54.202.179.226
```

## Create AWS Certificates

AWS IoT Core device needs _X.509 device certificate_ to connect

* Download Amazon Root CA certificate using `curl`

```
$ cd ~
$ mkdir certs
$ curl -o ./certs/AmazonRootCA1.pem \
        https://www.amazontrust.com/repository/AmazonRootCA1.pem

$ chmod 700 ~/certs
$ chmod 644 ~/certs/AmazonRootCA1.pem
```

* Create and download _X.509 device certificate_

```
$ cd ~
$ aws iot create-keys-and-certificate \
    --set-as-active \
    --certificate-pem-outfile "./certs/device.pem.crt" \
    --public-key-outfile "./certs/public.pem.key" \
    --private-key-outfile "./certs/private.pem.key"

$ chmod 644 ~/certs/*
$ chmod 600 ~/certs/private.pem.key
```

## Associate Namecheap domain to AWS EC2 instance

Source: [Associate Namecheap domain to AWS EC2 instance](https://u.osu.edu/walujo.1/2016/07/07/associate-namecheap-domain-to-amazon-ec2-instance/)

NOTE: the following instruction have been validated (Jun 2024) to work.

* Log into NameCheap.com and Amazon Web Services (AWS).
* In your NameCheap.com dashboard, go to “Domain List” and locate the domain name you want to point to AWS. Click the “manage” button. On the next page, click “Advanced DNS” tab. Under host records section, you should see 2 entries with “@” and “www”. For newly created domain, there may only be one entry only "@".
* Switch to AWS management console and go to your EC2 instance.
* Copy the public IP address and public DNS
* Switch back to NameCheap.com, locate entry with “@” symbol, set type to “A Record” and set value to public IP address.
* Locate entry with “www” or add one, set type to “CNAME Record” and set value to public DNS.
* Apply your changes and you’re done!
* You may have to wait a little before the association takes place. I’d say about 5 minutes. Now open your browse and type your domain name, it should now point to your EC2 instance.

{% hint style="info" %}
To be Investigated!!!

Source: [https://techgenix.com/namecheap-aws-ec2-linux/](https://techgenix.com/namecheap-aws-ec2-linux/) and [https://www.namecheap.com/support/knowledgebase/article.aspx/10371/2208/how-do-i-link-my-domain-to-amazon-web-services/](https://www.namecheap.com/support/knowledgebase/article.aspx/10371/2208/how-do-i-link-my-domain-to-amazon-web-services/)

Both articles suggest using the AWS Route53 that is $0.50/month (as of Jun 2024). It seems to be more complicated setup. Maybe suitable for production heavy traffics. Investigate the PROs & CONs.&#x20;
{% endhint %}

## Setup Reverse Proxy Apache httpd

The "reverse proxy" forward the request from Apache httpd to the docker http server, for example, running the "streamlit" web application on port 8501. In the following example, the httpd has been setup for "https" using the self-signed SSL certificate, see [HTTPS Setup](../https-setup). Make the reverse proxy configuration in the `/etc/httpd/conf.d/ssl.conf` file as follows:

```
<VirtualHost *:443>
#    ServerName example.com
    SSLEngine on
    SSLCertificateFile /etc/pki/tls/certs/server.crt
    SSLCertificateKeyFile /etc/pki/tls/private/server.key

    ProxyPreserveHost On
    ProxyPass "/" "http://0.0.0.0:8501/"
    ProxyPassReverse "/" "http://0.0.0.0:8501/"
    ProxyPass         "_stcore/stream" "http://0.0.0.0:8501/_stcore/stream"
    ProxyPassReverse  "_stcore/stream" "http://0.0.0.0:8501/_stcore/stream"
</VirtualHost>
```

NOTE: in case of the streamlit web application, the following additional setup are also needed:

```
SSLProxyEngine on

RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://0.0.0.0:8501/$1 [P,L]
```

{% hint style="info" %}
Make sure to restart the Apache httpd server: `sudo systemctl restart httpd`


{% endhint %}
