Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example wordpress #818

Merged
merged 50 commits into from
Oct 7, 2022
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
f6c0ebc
Wordpress example: work started
Jul 18, 2022
fba679a
some boilerplate code added
Jul 22, 2022
bcb4a33
using Fabric modules, CloudSQL internal IP - first approximation
Aug 9, 2022
cc60ae8
next iteration of code refining (WiP)
Aug 19, 2022
38e734e
Merge branch 'master' of https://github.com/skalolazka/cloud-foundati…
Aug 23, 2022
826e245
Merge branch 'GoogleCloudPlatform:master' into example-wordpress
skalolazka Aug 23, 2022
2f02f95
Merge branch 'example-wordpress' of https://github.com/skalolazka/clo…
Aug 23, 2022
fd52c4c
Merge branch 'GoogleCloudPlatform:master' into example-wordpress
skalolazka Aug 24, 2022
9b22eca
Merge branch 'example-wordpress' of https://github.com/skalolazka/clo…
Aug 24, 2022
216afda
update readme
bensadikgoogle Aug 25, 2022
ede1b3b
Merge branch 'example-wordpress' of https://github.com/skalolazka/clo…
Aug 29, 2022
2e76411
Merge branch 'GoogleCloudPlatform:master' into example-wordpress
skalolazka Aug 29, 2022
d27f09e
more code refactoring
Aug 31, 2022
c886fe1
Merge branch 'example-wordpress' of https://github.com/skalolazka/clo…
Aug 31, 2022
e608681
formatting
Aug 31, 2022
8464fc9
variables and outputs from tfdoc
Aug 31, 2022
d9a9996
Merge branch 'GoogleCloudPlatform:master' into example-wordpress
skalolazka Aug 31, 2022
88aa768
missing API adedd
Sep 9, 2022
123ae28
Merge branch 'example-wordpress' of https://github.com/skalolazka/clo…
Sep 9, 2022
6b45df5
Merge branch 'GoogleCloudPlatform:master' into example-wordpress
skalolazka Sep 15, 2022
fa68ed4
moving Wordpress to the right folder
Sep 15, 2022
2aefab0
Changes to README, vars samples and architecture diagram
erivarola Sep 15, 2022
2330d3e
Merge branch 'example-wordpress' of https://github.com/skalolazka/clo…
erivarola Sep 15, 2022
c811269
more info in the readme (org. policy and other)
skalolazka Sep 15, 2022
0b5b9c5
comments on separate lines
Sep 20, 2022
9c8969c
one block for code instead of three
Sep 20, 2022
4379525
typos and style corrections
Sep 21, 2022
0722f7d
variables alphabetically
Sep 21, 2022
d95f5d9
more readability
Sep 21, 2022
dbdaeda
style in locals
Sep 21, 2022
256b1b7
Merge branch 'master' into example-wordpress
skalolazka Sep 21, 2022
b5a5150
docker image tag added
Oct 5, 2022
b11ae47
passwords: either specified or random
Oct 5, 2022
0411dbb
ip_ranges var
Oct 6, 2022
bea9272
removed unnecessary README
Oct 6, 2022
c72d355
principals varibale description: users
Oct 6, 2022
c205660
principals: rights list
Oct 6, 2022
b6dcde6
Info on the VPC serverless connector
skalolazka Oct 6, 2022
bb436e4
Merge branch 'GoogleCloudPlatform:master' into example-wordpress
skalolazka Oct 6, 2022
aa3c6ab
explanation on accessing the installation
skalolazka Oct 6, 2022
c770abd
files restructured, connector added separately
Oct 6, 2022
e9779e3
locals moved to main
Oct 7, 2022
07f89e0
connector creation in a variable
Oct 7, 2022
2f8a03a
style and a note on password change
skalolazka Oct 7, 2022
b108b12
Merge branch 'master' into example-wordpress
skalolazka Oct 7, 2022
00b3383
Merge branch 'master' into example-wordpress
ludoo Oct 7, 2022
8a8a3fd
firewall unnecessary
Oct 7, 2022
8eae352
existing connector - variable
Oct 7, 2022
eb47e03
formatting
Oct 7, 2022
54290fb
Merge branch 'master' into example-wordpress
skalolazka Oct 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions blueprints/third-party-solutions/wordpress/cloudrun/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Wordpress deployment on Cloud Run

43% of the Web is built on Wordpress. Because of its simplicity and versatility, Wordpress can be used for internal websites as well as customer facing e-commerce platforms in small to large businesses, while still offering security.

This repository contains the necessary Terraform files to deploy a functioning new Wordpress website exposed to the public internet with minimal technical overhead.

This architecture can be used for the following use cases and more:

* Blog
* Intranet / internal Wiki
* E-commerce platform

## Architecture

![Wordpress on Cloud Run](images/architecture.png "Wordpress on Cloud Run")

The main components that are deployed in this architecture are the following (you can learn about them by following the hyperlinks):

* [Cloud Run](https://cloud.google.com/run): serverless PaaS offering to host containers for web-oriented applications, while offering security, scalability and easy versioning
* [Cloud SQL](https://cloud.google.com/sql): Managed solution for SQL databases
* [VPC Serverless Connector](https://cloud.google.com/vpc/docs/serverless-vpc-access): Solution to access the CloudSQL VPC from Cloud Run, using only internal IP addresses

## Setup

### Prerequisites

#### Setting up the project for the deployment

This example will deploy all its resources into the project defined by the `project_id` variable. Please note that we assume this project already exists. However, if you provide the appropriate values to the `project_create` variable, the project will be created as part of the deployment.

If `project_create` is left to null, the identity performing the deployment needs the `owner` role on the project defined by the `project_id` variable. Otherwise, the identity performing the deployment needs `resourcemanager.projectCreator` on the resource hierarchy node specified by `project_create.parent` and `billing.user` on the billing account specified by `project_create.billing_account_id`.

### Deployment

#### Step 0: Cloning the repository

If you want to deploy from your Cloud Shell, click on the image below, sign in if required and when the prompt appears, click on “confirm”.

[<p align="center"> <img alt="Open Cloudshell" width = "300px" src="images/button.png" /> </p>](https://ssh.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fcloud-foundation-fabric&cloudshell_print=cloud-shell-readme.txt&cloudshell_working_dir=blueprints%2Fthird-party-solutions%2Fwordpress)

Otherwise, in your console of choice:
``` {shell}
git clone https://github.com/GoogleCloudPlatform/cloud-foundation-fabric
```

Before you deploy the architecture, you will need at least the following information (for more precise configuration see the Variables section):

* The project ID.
* A Google Cloud Registry path to a Wordpress container image.
skalolazka marked this conversation as resolved.
Show resolved Hide resolved

#### Step 1: Add Wordpress image

In order to deploy the Wordpress service to Cloud Run, you need to store the [Wordpress image](https://hub.docker.com/r/bitnami/wordpress/) in Google Cloud Registry (GCR).

Make sure that the Google Container Registry API is enabled and run the following commands in your Cloud Shell environment with your `project_id` in place of the `MY_PROJECT` placeholder:

``` {shell}
docker pull bitnami/wordpress:6.0.2
docker tag bitnami/wordpress gcr.io/MY_PROJECT/wordpress
docker push gcr.io/MY_PROJECT/wordpress
```

**Note**: This example has been built for this particular Docker image. If you decide to use another one, this example might not work (or you can edit the variables in the Terraform files).

#### Step 2: Deploy resources

Once you have the required information, head back to your cloned repository. Make sure you’re in the directory of this tutorial (where this README is in).

Configure the Terraform variables in your `terraform.tfvars` file. See [terraform.tfvars.sample](terraform.tfvars.sample) as starting point - just copy it to `terraform.tfvars` and edit the latter. See the variables documentation below.

**Note**: If you have the [domain restriction org. policy](https://cloud.google.com/resource-manager/docs/organization-policy/restricting-domains) on your organization, you have to edit the `cloud_run_invoker` variable and give it a value that will be accepted in accordance to your policy.

Initialize your Terraform environment and deploy the resources:

``` {shell}
terraform init
terraform apply
```
The resource creation will take a few minutes.

**Note**: you might get the following error (or a similar one):
``` {shell}
│ Error: resource is in failed state "Ready:False", message: Revision '...' is not ready and cannot serve traffic.│
```
You might try to reapply at this point, the Cloud Run service just needs several minutes.

#### Step 3: Use the created resources

Upon completion, you will see the output with the values for the Cloud Run service and the user and password to access the `/admin` part of the website. You can also view it later with:
``` {shell}
terraform output
# or for the concrete variable:
terraform output cloud_run_service
```
1. Open your browser at the URL that you get with that last command, and you will see your Wordpress installation.
2. Add "/admin" in the end of the URL and log in to the admin interface, using the outputs "wp_user" and "wp_password".

### Cleaning up your environment

The easiest way to remove all the deployed resources is to run the following command in Cloud Shell:

``` {shell}
terraform destroy
```

The above command will delete the associated resources so there will be no billable charges made afterwards.
skalolazka marked this conversation as resolved.
Show resolved Hide resolved
<!-- BEGIN TFDOC -->

## Variables

| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [project_id](variables.tf#L66) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
| [wordpress_image](variables.tf#L77) | Image to run with Cloud Run, starts with \"gcr.io\" | <code>string</code> | ✓ | |
| [cloud_run_invoker](variables.tf#L18) | IAM member authorized to access the end-point (for example, 'user:YOUR_IAM_USER' for only you or 'allUsers' for everyone) | <code>string</code> | | <code>&#34;allUsers&#34;</code> |
| [cloudsql_password](variables.tf#L24) | CloudSQL password (will be randomly generated by default) | <code>string</code> | | <code>null</code> |
| [ip_ranges](variables.tf#L31) | CIDR blocks: VPC serverless connector, Private Service Access(PSA) for CloudSQL, CloudSQL VPC | <code title="object&#40;&#123;&#10; connector &#61; string&#10; psa &#61; string&#10; sql_vpc &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; connector &#61; &#34;10.8.0.0&#47;28&#34;&#10; psa &#61; &#34;10.60.0.0&#47;24&#34;&#10; sql_vpc &#61; &#34;10.0.0.0&#47;20&#34;&#10;&#125;">&#123;&#8230;&#125;</code> |
| [prefix](variables.tf#L45) | Unique prefix used for resource names. Not used for project if 'project_create' is null. | <code>string</code> | | <code>&#34;&#34;</code> |
| [principals](variables.tf#L51) | List of users to give rights to (CloudSQL admin, client and instanceUser, Logging admin, Service Account User and TokenCreator), eg '[email protected]'. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [project_create](variables.tf#L57) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object&#40;&#123;&#10; billing_account_id &#61; string&#10; parent &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [region](variables.tf#L71) | Region for the created resources | <code>string</code> | | <code>&#34;europe-west4&#34;</code> |
| [wordpress_password](variables.tf#L88) | Password for the Wordpress user (will be randomly generated by default) | <code>string</code> | | <code>null</code> |
| [wordpress_port](variables.tf#L82) | Port for the Wordpress image (8080 by default) | <code>number</code> | | <code>8080</code> |

## Outputs

| name | description | sensitive |
|---|---|:---:|
| [cloud_run_service](outputs.tf#L17) | CloudRun service URL | ✓ |
| [cloudsql_password](outputs.tf#L23) | CloudSQL password | ✓ |
| [wp_password](outputs.tf#L34) | Wordpress user password | ✓ |
| [wp_user](outputs.tf#L29) | Wordpress username | |

<!-- END TFDOC -->
78 changes: 78 additions & 0 deletions blueprints/third-party-solutions/wordpress/cloudrun/cloudsql.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


resource "random_password" "cloudsql_password" {
length = 8
}

# create a VPC for CloudSQL
module "vpc" {
source = "../../../../modules/net-vpc"
project_id = module.project.project_id
name = "${local.prefix}sql-vpc"
subnets = [
{
ip_cidr_range = var.ip_ranges.sql_vpc
name = "subnet"
region = var.region
secondary_ip_range = {}
}
]

# Private Service Access
psa_config = {
ranges = {
cloud-sql = var.ip_ranges.psa
}
routes = null
}
}


# set up firewall for CloudSQL
module "firewall" {
source = "../../../../modules/net-vpc-firewall"
project_id = module.project.project_id
network = module.vpc.name
admin_ranges = [var.ip_ranges.sql_vpc]
skalolazka marked this conversation as resolved.
Show resolved Hide resolved
}


# create a VPC connector for the ClouSQL VPC
resource "google_vpc_access_connector" "connector" {
project = module.project.project_id
name = "${local.prefix}wp-connector"
region = var.region
ip_cidr_range = var.ip_ranges.connector
network = module.vpc.self_link
}


# Set up CloudSQL
module "cloudsql" {
source = "../../../../modules/cloudsql-instance"
project_id = module.project.project_id
network = module.vpc.self_link
name = "${local.prefix}mysql"
region = var.region
database_version = local.cloudsql_conf.database_version
tier = local.cloudsql_conf.tier
databases = [local.cloudsql_conf.db]
users = {
"${local.cloudsql_conf.user}" = "${local.cloudsql_conf.pass}"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions blueprints/third-party-solutions/wordpress/cloudrun/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


locals {
skalolazka marked this conversation as resolved.
Show resolved Hide resolved
all_principals_iam = [for k in var.principals : "user:${k}"]
cloudsql_conf = {
database_version = "MYSQL_8_0"
tier = "db-g1-small"
db = "wp-mysql"
user = "admin"
pass = var.cloudsql_password == null ? random_password.cloudsql_password.result : var.cloudsql_password
}
iam = {
# CloudSQL
"roles/cloudsql.admin" = local.all_principals_iam
"roles/cloudsql.client" = local.all_principals_iam
"roles/cloudsql.instanceUser" = local.all_principals_iam
# common roles
"roles/logging.admin" = local.all_principals_iam
"roles/iam.serviceAccountUser" = local.all_principals_iam
"roles/iam.serviceAccountTokenCreator" = local.all_principals_iam
}
prefix = var.prefix == null ? "" : "${var.prefix}-"
wp_user = "user"
wp_pass = var.wordpress_password == null ? random_password.wp_password.result : var.wordpress_password
}
93 changes: 93 additions & 0 deletions blueprints/third-party-solutions/wordpress/cloudrun/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


# either create a project or set up the given one
module "project" {
source = "../../../../modules/project"
name = var.project_id
parent = try(var.project_create.parent, null)
billing_account = try(var.project_create.billing_account_id, null)
project_create = var.project_create != null
prefix = var.project_create == null ? null : var.prefix
iam = var.project_create != null ? local.iam : {}
iam_additive = var.project_create == null ? local.iam : {}
services = [
"run.googleapis.com",
"logging.googleapis.com",
"monitoring.googleapis.com",
"sqladmin.googleapis.com",
"sql-component.googleapis.com",
"vpcaccess.googleapis.com",
"servicenetworking.googleapis.com"
]
}

resource "random_password" "wp_password" {
length = 8
}

# create the Cloud Run service
module "cloud_run" {
source = "../../../../modules/cloud-run"
project_id = module.project.project_id
name = "${local.prefix}cr-wordpress"
region = var.region

containers = [{
image = var.wordpress_image
ports = [{
name = "http1"
protocol = null
container_port = var.wordpress_port
}]
options = {
command = null
args = null
env_from = null
# set up the database connection
env = {
"APACHE_HTTP_PORT_NUMBER" : var.wordpress_port
"WORDPRESS_DATABASE_HOST" : module.cloudsql.ip
"WORDPRESS_DATABASE_NAME" : local.cloudsql_conf.db
"WORDPRESS_DATABASE_USER" : local.cloudsql_conf.user
"WORDPRESS_DATABASE_PASSWORD" : local.cloudsql_conf.pass
"WORDPRESS_USERNAME" : local.wp_user
"WORDPRESS_PASSWORD" : local.wp_pass
}
}
resources = null
volume_mounts = null
}]

iam = {
"roles/run.invoker" : [var.cloud_run_invoker]
}

revision_annotations = {
autoscaling = {
min_scale = 1
max_scale = 2
}
# connect to CloudSQL
cloudsql_instances = [module.cloudsql.connection_name]
vpcaccess_connector = null
# allow all traffic
vpcaccess_egress = "all-traffic"
vpcaccess_connector = google_vpc_access_connector.connector.self_link
}
ingress_settings = "all"
}
38 changes: 38 additions & 0 deletions blueprints/third-party-solutions/wordpress/cloudrun/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "cloud_run_service" {
description = "CloudRun service URL"
value = module.cloud_run.service.status[0].url
sensitive = true
}

output "cloudsql_password" {
description = "CloudSQL password"
value = local.cloudsql_conf.pass
sensitive = true
}

output "wp_user" {
description = "Wordpress username"
value = local.wp_user
}

output "wp_password" {
description = "Wordpress user password"
value = local.wp_pass
sensitive = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
prefix = "wp"
project_id = "my-wordpress-project"
wordpress_image = "gcr.io/my-wordpress-project/wordpress"
Loading