Skip to content

Commit

Permalink
Code improvement, bug fixes and adding the dynamic provisioning based…
Browse files Browse the repository at this point in the history
… on the settings.
  • Loading branch information
fvilarin committed May 21, 2024
1 parent 94f0755 commit 0d73aa9
Show file tree
Hide file tree
Showing 48 changed files with 1,307 additions and 1,311 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/.idea/
/iac/.terraform*
/iac/.credentials
/iac/.terraform*
/iac/terraform.tfstate*
/iac/*/settings.json
57 changes: 31 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,57 @@ Getting Started

### Introduction
This is a demo project for education/training purposes of DevOps.

It automates (using **Terraform**) the provisioning of a static website using the following resources in Akamai
Connected Cloud (former Linode):
Cloud Computing (former Linode) environment:
- **Object Storage**: S3 compliant object storage.

Please check the files `iac/linode*.tf` for more details.

Then, It starts the provisioning of the Akamai Intelligent Platform resources that includes:
- **CP Code**: Creates the identifier used for reporting and billing of the CDN traffic. (Please check the file
`iac/akamai-cpcode.tf` for more details).
- **Edge Hostname**: Creates the CDN hostname that will receive the traffic of the website. (Please check the file
`iac/akamai-edgehostname.tf` for more details).
- **Edge Certificate**: Creates the CDN TLS certificate used to enable HTTPs traffic of the website. (Please check the
file `iac/akamai-cps.tf` for more details).
- **Edge DNS entries**: Creates all required DNS entries in the Edge DNS service to validate/point to the CDN
configuration. (Please check the file `iac/akamai-edgedns.tf` for more details).
- **Property**: Creates the CDN configuration containing all rules such as: caching, redirect, performance settings,
etc. (Please check the file `iac/akamai-property.tf` for more details).
- **Security**: Creates the Security configuration containing all protections such as: Network Lists, DDoS, IP/GEO firewall, WAF,
It also do the the provisioning of the Akamai Edge resources that includes:
- **CP Code**: Identifier used for reporting and billing of the traffic. (Please check the file`iac/akamai-cpcode.tf`
for more details).
- **Edge Hostname**: Hostname that will deliver the content of the website. (Please check the file
`iac/akamai-edgehostname.tf` for more details).
- **Edge DNS entries**: All required DNS entries to validate the TLS certificate and also point to websiteto the Edge
Hostname. (Please check the file `iac/akamai-edgedns.tf` for more details).
- **Property**: Configuration that contains the delivery rules such as: caching, redirect, performance settings, etc.
(Please check the file `iac/akamai-property.tf` for more details).
- **Security**: Configuration that contains all security protections such as: Network Lists, DDoS, IP/GEO firewall, WAF,
Bot Management, etc. (Please check the file `iac/akamai-security*.tf` for more details).

All the Terraform files use `variables` that are stored in the `iac/variables.tf`, `iac/general/settings.json`,
`iac/certificate/settings.json`, `iac/dns/settings.json`, `iac/property/settings.json` and
`iac/security/settings.json`.
`iac/dns/settings.json`, `iac/property/settings.json` and `iac/security/settings.json`.

The tokens and credentials must be defined in `iac/.credentials` file. Please follow the template
`iac/.credentials.template`.

You can customize the provisioning by editing these files. Use the template as base.

You can change the attributes of the provisioning by editing these files.
### Requirements
- [`Terraform 1.5.x`](https://www.terraform.io) - IaC automation tool.
- [`Akamai Cloud Computing account`](https://cloud.linode.com)
- `Any linux distribution with Kernel 5.x or later` or
- `MacOS - Catalina or later` or
- `MS-Windows 10 or later with WSL2`

### Workflow

The workflow will start automatically in every commit of changes in this project, starting the execution of a CI/CD
pipeline configured in **Jenkins**. Please check this [repo](https://github.com/fvilarinho/cicdzerotohero) to see how to
provision the CI/CD pipeline.
pipeline configured in **Jenkins**. Please check this [repo](https://github.com/fvilarinho/cicdzerotohero) to see how to provision the CI/CD pipeline.

The provisioning state is stored in the **Object Storage** (that should be provisioned in advance). By default, it uses
Akamai Connected Cloud, but you can change to any provider you want.
The provisioning state is stored in an **Object Storage** (that should be provisioned in advance). By default, it uses
Akamai Cloud Computing, but you can use any other provider compatible with S3.

### Documentation

Follow the documentation below to know more about Akamai:

- [**How to create Akamai EdgeGrid credentials**](https://techdocs.akamai.com/developer/docs/make-your-first-api-call)
- [**How to create Akamai Connected Cloud credentials**](https://www.linode.com/docs/api)
- [**How to create an Object Storage**](https://www.linode.com/docs/guides/platform/object-storage)
- [**List of Akamai Connected Cloud Regions**](https://www.linode.com/docs/api/regions/)
- [**Akamai Techdocs**](https://techdocs.akamai.com)
- [**Akamai Connected Cloud Documentation**](https://www.linode.com/docs/)
- [**How to create Akamai EdgeGrid credentials**](https://techdocs.akamai.com/developer/docs/make-your-first-api-call)
- [**How to create Akamai Cloud Computing credentials**](https://www.linode.com/docs/api)
- [**How to create an Akamai Cloud Computing Object Storage**](https://www.linode.com/docs/guides/platform/object-storage)
- [**List of Akamai Cloud Computing Regions**](https://www.linode.com/docs/api/regions/)
- [**Akamai Cloud Computing Documentation**](https://www.linode.com/docs/)

### Important notes
- **If any phase got errors or violations, the pipeline will stop.**
Expand Down
27 changes: 20 additions & 7 deletions deploy.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
#!/bin/bash

# Checks the dependencies to run this script.
# Checks the dependencies of this script.
function checkDependencies() {
if [ ! -f "$CREDENTIALS_FILENAME" ]; then
echo "The credentials filename was not found! Please finish the setup first to continue!"

exit 1
fi

if [ -z "$TERRAFORM_CMD" ]; then
echo "Terraform is not installed! Please install it first to continue!"
echo "terraform is not installed! Please install it first to continue!"

exit 1
fi
}

# Prepares the environment to run this script.
# Prepares the environment to execute this script.
function prepareToExecute() {
source functions.sh

Expand All @@ -18,23 +24,30 @@ function prepareToExecute() {
cd iac || exit 1
}

# Deploys the infrastructure based on IaC files.
# Starts the provisioning based on the IaC files.
function deploy() {
$TERRAFORM_CMD init \
-upgrade \
-migrate-state || exit 1

$TERRAFORM_CMD plan || exit 1
$TERRAFORM_CMD plan -out /tmp/plan || exit 1

$TERRAFORM_CMD apply \
-auto-approve
-auto-approve \
/tmp/plan
}

# Clean-up.
function cleanUp() {
rm -f /tmp/plan
}

# Main functions.
# Main function.
function main() {
prepareToExecute
checkDependencies
deploy
cleanUp
}

main
22 changes: 19 additions & 3 deletions functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
# Shows the labels.
function showLabel() {
if [[ "$0" == *"undeploy.sh"* ]]; then
echo "** Undeploy **"
echo "** Undeploy ** "
elif [[ "$0" == *"deploy.sh"* ]]; then
echo "** Deploy **"
echo "** Deploy ** "
fi

echo
Expand All @@ -20,6 +20,17 @@ function showBanner() {
showLabel
}

# Gets a credential value.
function getCredential() {
if [ -f "$CREDENTIALS_FILENAME" ]; then
value=$(awk -F'=' '/'$1'/,/^\s*$/{ if($1~/'$2'/) { print substr($0, length($1) + 2) } }' "$CREDENTIALS_FILENAME" | tr -d '"' | tr -d ' ')
else
value=
fi

echo "$value"
}

# Prepares the environment to execute the commands of this script.
function prepareToExecute() {
# Required files/paths.
Expand All @@ -30,7 +41,12 @@ function prepareToExecute() {
export TERRAFORM_CMD=$(which terraform)

# Environment variables.
export TF_VAR_credentialsFilename="$CREDENTIALS_FILENAME"
export TF_VAR_linodeToken=$(getCredential "linode" "token")
export TF_VAR_edgeGridAccountKey=$(getCredential "edgegrid" "account_key")
export TF_VAR_edgeGridHost=$(getCredential "edgegrid" "host")
export TF_VAR_edgeGridAccessToken=$(getCredential "edgegrid" "access_token")
export TF_VAR_edgeGridClientToken=$(getCredential "edgegrid" "client_token")
export TF_VAR_edgeGridClientSecret=$(getCredential "edgegrid" "client_secret")
}

prepareToExecute
10 changes: 4 additions & 6 deletions iac/.credentials.template
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
[linode]
token = <token>

[edgegrid]
account_key = <account-key>
client_secret = <client-secret>
host = <host>
access_token = <access-token>
client_token = <client-token>

[linode]
token = <token>
aws_access_key_id = <linode-object-storage-access-key>
aws_secret_access_key = <linode-object-storage-secret-key>
client_secret = <client-secret>
2 changes: 1 addition & 1 deletion iac/akamai-cpcode.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ resource "akamai_cp_code" "default" {
contract_id = local.generalSettings.contract
group_id = local.generalSettings.group
product_id = local.propertySettings.product
name = local.propertySettings.id
name = local.propertySettings.name
}
87 changes: 0 additions & 87 deletions iac/akamai-cps.tf

This file was deleted.

34 changes: 27 additions & 7 deletions iac/akamai-edgedns.tf
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
# Definition of the Edge DNS TLS certificate validation entries.
data "akamai_property_hostnames" "default" {
for_each = { for property in local.propertySettings.hostnames : property.name => property }
contract_id = local.generalSettings.contract
group_id = local.generalSettings.group
property_id = akamai_property.default[each.key].id
version = akamai_property.default[each.key].latest_version
depends_on = [ akamai_property.default ]
}

resource "akamai_dns_record" "certificateValidation" {
for_each = { for property in local.propertySettings.hostnames : property.name => property }
name = data.akamai_property_hostnames.default[each.key].hostnames[0].cert_status[0].hostname
recordtype = "CNAME"
ttl = 30
zone = local.dnsSettings.zone
target = [data.akamai_property_hostnames.default[each.key].hostnames[0].cert_status[0].target]
depends_on = [data.akamai_property_hostnames.default]
}

# Definition of the Edge DNS general entries.
resource "akamai_dns_record" "records" {
for_each = { for record in local.dnsSettings.records: record.id => record }
zone = local.dnsSettings.id
name = "${each.value.id}.${local.dnsSettings.id}"
for_each = { for record in local.dnsSettings.records: record.name => record }
zone = local.dnsSettings.zone
name = "${each.key}.${local.dnsSettings.zone}"
recordtype = each.value.type
ttl = each.value.ttl
target = [ each.value.value ]
}

# Definition of the Edge DNS entries that point to the Edge Hostname.
resource "akamai_dns_record" "default" {
for_each = toset(local.propertySettings.hostnames)
zone = local.dnsSettings.id
name = each.value
for_each = { for property in local.propertySettings.hostnames : property.name => property }
zone = local.dnsSettings.zone
name = "${each.key}.${local.dnsSettings.zone}"
recordtype = "CNAME"
ttl = local.dnsSettings.defaultTtl
target = [ akamai_edge_hostname.default.edge_hostname ]
target = [ akamai_edge_hostname.default[each.key].edge_hostname ]
depends_on = [ akamai_edge_hostname.default ]
}
5 changes: 2 additions & 3 deletions iac/akamai-edgehostname.tf
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Definition of the Edge Hostname. This is the hostname that must be used in the Edge DNS entries
# of all hostnames that will pass through the CDN.
resource "akamai_edge_hostname" "default" {
for_each = { for property in local.propertySettings.hostnames : property.name => property }
contract_id = local.generalSettings.contract
group_id = local.generalSettings.group
product_id = local.propertySettings.product
edge_hostname = "${local.propertySettings.id}.edgekey.net"
edge_hostname = "${local.propertySettings.name}-${each.value.origin.name}.edgesuite.net"
ip_behavior = local.propertySettings.ipVersion
certificate = akamai_cps_dv_enrollment.default.id
depends_on = [ akamai_cps_dv_enrollment.default ]
}
Loading

0 comments on commit 0d73aa9

Please sign in to comment.