diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7d5de99 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +clouds.yaml +.terraform +terraform.tfstate +.terragrunt-cache \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..caff8b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +The 3-Clause BSD License + +Copyright (c) 2013-2017, OVH SAS. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of OVH SAS nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY OVH SAS AND CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL OVH SAS AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3247ef3 --- /dev/null +++ b/README.md @@ -0,0 +1,89 @@ +# Terraform Recipe: Boot a single Jitsi Video conferencing instance on OVHCloud + +## Description + +This recipe helps you bootstrap a simple [Jitsi](https://jitsi.org) instance on +OVHCloud. + +This could be very useful for small teams/companies which could have an +urging need of a simple videoconferencing solution due to covid19. + +This is a very simple and stupid deployment, only secured with https and basic firewalling +feature. To use with CAUTION. + +## Requirements + +- an OVHCloud [public cloud](https://www.ovhcloud.com/fr/public-cloud) project. +- Hashicorp [terraform](https://www.terraform.io) + +## Getting Started + +1. Create your Openstack API clouds.yaml file. + +``` +mkdir -p ~/.config/openstack +cat >> ~/.config/openstack/clouds.yaml < $CRON_FILE +echo "/usr/local/sbin/certbot-auto renew >> /var/log/le-renew.log" >> $CRON_FILE + +CERT_KEY="/etc/letsencrypt/live/$DOMAIN/privkey.pem" +CERT_CRT="/etc/letsencrypt/live/$DOMAIN/fullchain.pem" + +if [ -f /etc/nginx/sites-enabled/$DOMAIN.conf ] ; then + + ./certbot-auto certonly --noninteractive \ + --webroot --webroot-path /usr/share/jitsi-meet \ + -d $DOMAIN \ + --agree-tos --email $EMAIL + + echo "Configuring nginx" + + CONF_FILE="/etc/nginx/sites-available/$DOMAIN.conf" + CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g') + CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g') + sed -i "s/ssl_certificate_key\ \/etc\/jitsi\/meet\/.*key/ssl_certificate_key\ $CERT_KEY_ESC/g" \ + $CONF_FILE + CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g') + CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g') + sed -i "s/ssl_certificate\ \/etc\/jitsi\/meet\/.*crt/ssl_certificate\ $CERT_CRT_ESC/g" \ + $CONF_FILE + + echo "service nginx reload" >> $CRON_FILE + service nginx reload + +elif [ -f /etc/apache2/sites-enabled/$DOMAIN.conf ] ; then + + ./certbot-auto certonly --noninteractive \ + --webroot --webroot-path /usr/share/jitsi-meet \ + -d $DOMAIN \ + --agree-tos --email $EMAIL + + echo "Configuring apache2" + + CONF_FILE="/etc/apache2/sites-available/$DOMAIN.conf" + CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g') + CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g') + sed -i "s/SSLCertificateKeyFile\ \/etc\/jitsi\/meet\/.*key/SSLCertificateKeyFile\ $CERT_KEY_ESC/g" \ + $CONF_FILE + CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g') + CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g') + sed -i "s/SSLCertificateFile\ \/etc\/jitsi\/meet\/.*crt/SSLCertificateFile\ $CERT_CRT_ESC/g" \ + $CONF_FILE + + echo "service apache2 reload" >> $CRON_FILE + service apache2 reload +else + service jitsi-videobridge stop + + ./certbot-auto certonly --noninteractive \ + --standalone \ + -d $DOMAIN \ + --agree-tos --email $EMAIL + + echo "Configuring jetty" + + CERT_P12="/etc/jitsi/videobridge/$DOMAIN.p12" + CERT_JKS="/etc/jitsi/videobridge/$DOMAIN.jks" + # create jks from certs + openssl pkcs12 -export \ + -in $CERT_CRT -inkey $CERT_KEY -passout pass:changeit > $CERT_P12 + keytool -importkeystore -destkeystore $CERT_JKS \ + -srckeystore $CERT_P12 -srcstoretype pkcs12 \ + -noprompt -storepass changeit -srcstorepass changeit + + service jitsi-videobridge start + +fi + +# the cron file that will renew certificates +chmod a+x $CRON_FILE diff --git a/live/terragrunt/terragrunt.hcl b/live/terragrunt/terragrunt.hcl new file mode 100644 index 0000000..18c4dcd --- /dev/null +++ b/live/terragrunt/terragrunt.hcl @@ -0,0 +1,22 @@ +terraform { + source = "../.." +} + +remote_state { + backend = "swift" + config = { + cloud = "jitsi" + region_name = "GRA" + container = "jitsi" + archive_container = "archive-jitsi" + state_name = "tfstate.tf" + } +} + +inputs = { + name = "jitsi" + cloud_name = "jitsi" + region_name = "GRA5" + email = "myjitsi@email.com" + allowed_prefixes = ["${chomp(run_cmd("/bin/sh", "-c", "curl --silent --fail https://api.ipify.org"))}/32"] +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..b1e9d52 --- /dev/null +++ b/main.tf @@ -0,0 +1,148 @@ +terraform { + backend "swift" {} +} + +provider openstack { + cloud = var.cloud_name + region = var.region_name +} + +resource tls_private_key priv { + algorithm = "ECDSA" + ecdsa_curve = "P384" +} + +resource openstack_compute_keypair_v2 keypair { + name = var.ssh_keypair_name + public_key = tls_private_key.priv.public_key_openssh +} + +# +# Network objects +# +data openstack_networking_network_v2 ext_net { + name = "Ext-Net" + tenant_id = "" +} + +data openstack_images_image_v2 image { + name = var.image_name + most_recent = true +} + +resource openstack_networking_secgroup_v2 secgroup { + name = var.name + description = "Security gropup for Jitsi" +} + +resource openstack_networking_secgroup_rule_v2 ingress_https_jitsi { + for_each = var.allowed_prefixes + + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 443 + port_range_max = 443 + remote_ip_prefix = each.key + security_group_id = openstack_networking_secgroup_v2.secgroup.id +} + +resource openstack_networking_secgroup_rule_v2 ingress_http_01_challenge { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 80 # required for http letsencrypt challenge + port_range_max = 80 + remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.secgroup.id +} + +resource openstack_networking_secgroup_rule_v2 ingress_tcp_ssh { + for_each = var.allowed_prefixes + + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 22 + port_range_max = 22 + remote_ip_prefix = each.key + security_group_id = openstack_networking_secgroup_v2.secgroup.id +} + +resource openstack_networking_port_v2 fip { + name = var.name + network_id = data.openstack_networking_network_v2.ext_net.id + admin_state_up = "true" + + security_group_ids = [openstack_networking_secgroup_v2.secgroup.id] +} + + +locals { + jitsi = [ + for ip in openstack_networking_port_v2.fip.all_fixed_ips : + ip + if length(replace(ip, "/[[:alnum:]]+:[^,]+/", "")) > 0 + ][0] + + ip_parts = split(".", local.jitsi) + fqdn = format("ip%s.ip-%s-%s-%s.eu", local.ip_parts[3], local.ip_parts[0], local.ip_parts[1], local.ip_parts[2]) + + user_data = { + hostname = local.fqdn + fqdn = local.fqdn + } + +} + +resource openstack_compute_instance_v2 vm { + name = var.name + image_id = data.openstack_images_image_v2.image.id + flavor_name = var.flavor_name + key_pair = openstack_compute_keypair_v2.keypair.name + + user_data = < /etc/apt/sources.list.d/jitsi-stable.list" +sudo apt-get -y update + +#first install with a self signed cert. then restart with letsencrypt +cat > /tmp/jitsi.seeds <