Skip to content
This repository has been archived by the owner on Oct 31, 2019. It is now read-only.

save wp-content data to a separate volume #16

Merged
merged 10 commits into from
Sep 1, 2017
Merged

Conversation

afeld
Copy link
Contributor

@afeld afeld commented Aug 29, 2017

Closes #7.

@afeld
Copy link
Contributor Author

afeld commented Aug 29, 2017

@Vermyndax It shows up! Now just need to figure out what hooks to use for mounting/unmounting.

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0  10G  0 disk

@Vermyndax
Copy link
Contributor

\o/

Ok, so when you initially create this EBS volume (in the setup of the infrastructure), you'd want to attach it to an EC2 instance and make the file system on it:

sudo mkfs -t ext4 /dev/xvdf

...this will make the filesystem.

Next you'll want to mount it at a mount point. If wordpress is installed in /var/www/html/wordpress, then you would normally do:

sudo mount /dev/xvdf /var/www/html/wordpress/wp-content

The wp-content directory will still exist on the root volume, but it will become invisible because of the mounting of the volume in that directory. That's normal and fine, since the server's immutable anyway. Now, anything written to /var/www/html/wordpress/wp-content will go on the attached EBS volume.

To make this EBS volume attached to the instance throughout it's lifespan, two things have to happen:

  1. The AWS orchestrator must attach the volume somehow... either through the console or an API call. Terraform would be handling this. this means the volume must not be attached to any other instance, which is where the real gotcha is... when terraform tears down the instance, it needs to detach the volume but not delete it

  2. The volume, once attached by AWS, will be visible to the operating system as /dev/whatever (likely xvdf)... so then the operating system must mount it in the folder like above. Assuming there was data on the volume, it would now come online in the wp-content folder. Theoretically.

To preserve the mount as a permanent part of the instance's life, you would edit /etc/fstab as per the AWS documentation, but that's where I'm not sure what the best approach is... would it be better to do it this way, or would it be better to have terraform handle the attachment/detachment and folder mounting as part of infrastructure provisioning and modification? I suspect it's the latter.

@afeld afeld force-pushed the persistent-volume branch from cb5c5d3 to dee0c3a Compare August 30, 2017 09:17
@afeld
Copy link
Contributor Author

afeld commented Aug 30, 2017

It works! 🎉 Test steps (which we should get into code at some point):

  1. Run terraform apply.
  2. Sign into the WordPress admin interface.
  3. Click Media on the sidebar.
  4. Upload something.
  5. Run terraform taint aws_instance.wordpress.
  6. Run terraform apply.
  7. Reload the Media Library page.
  8. Ensure the image still appears.

Pulled a few smaller pull requests out of this one, so will rebase as soon as those are in.

README.md Outdated
@@ -110,3 +110,13 @@ For initial or subsequent deployment:
```sh
terraform apply
```

Note that if the public IP address changes after you set up the site initially, you will need to [change the site URL](https://codex.wordpress.org/Changing_The_Site_URL#Changing_the_Site_URL) in WordPress.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I learned the hard way that WordPress saves the URL where it's accessed for the initial setup in the database, and therefore having the public IP change frequently was making parts of the site inaccessible. While a custom domain is what you'd actually use, an Elastic IP is good enough for now.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to look at installing the wp-cli to make changes like this easier to do from the machine itself in case you can't get in to the web interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call! Added as follow-up task: #22.

Copy link
Contributor

@Vermyndax Vermyndax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a little nit on the volume about setting the type.

@@ -0,0 +1,21 @@
resource "aws_ebs_volume" "wp_content" {
# TODO deletion protection
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@afeld Just a nit... When a "type" property isn't specified in this resource, it's created as a "standard" volume. Default for creating a volume in the console is "GP2" (General Purpose SSD). I'd recommend adding:
type = "gp2"
...just to keep things standardized I guess ;)
Ref: aws_ebs_volume

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Along with that, you'll want encryption at rest enabled as well.

afeld added 7 commits August 31, 2017 17:42
WordPress needs its database to be updated anytime the hostname changes
- this sidesteps the issue for the common case of the instance being
  replaced, by using an Elastic IP that will stay constant.
@afeld afeld force-pushed the persistent-volume branch from 303da4d to d7a6f1c Compare August 31, 2017 21:45
owner: "{{ apache_user }}"
group: "{{ apache_group }}"
state: directory
recurse: true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not positive that we want to allow automatic updates...? That would mean WordPress itself wouldn't be deployed immutably. Happy to take the conversation to an issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the upstream source that deploys Wordpress on the instance is in sync with the updates, it may not be too bad. Wordpress updates download into /wp-content/updates and then deploy into the main directory. Sometimes those updates contain schema updates for the database as well. Lots to consider.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, the way that I did this for our modified version of cf-ex-wordpress (deploying in cloud.gov) was to do some json in a particular schema, and feed that to wp-cli.

Relevant python bits here: cloud-gov/cf-ex-wordpress@25be580#diff-81085e34fc3ba4cf38cba76d477219bdR59 . I'm sure that could be turned into some ansible code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's worry about it separately, if that's ok with you both: #23.

@afeld
Copy link
Contributor Author

afeld commented Aug 31, 2017

Rebased and addressed the comments - should be ready to go!

sudo mv $DEST $OLDDEST
sudo mkdir -p $DEST

echo "$devpath $DEST ext4 defaults,nofail,noatime,nodiratime,barrier=0,data=writeback 0 2" | sudo tee -a /etc/fstab > /dev/null

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably check that it doesn't exist before appending to fstab, yeah?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will look into the best way to do that. This script got complex enough that I'm considering changing it to Ansible (as a follow-up), which takes care of checks like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(but let me know if you know of an example)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be able to do with an egrep and regex:

if ! egrep "^${devpath}" /etc/fstab; then
  echo "$devpath $DEST ... etc
fi

@afeld afeld changed the title [WORK IN PROGRESS] save wp-content data to a separate volume save wp-content data to a separate volume Sep 1, 2017
@afeld
Copy link
Contributor Author

afeld commented Sep 1, 2017

Ready for another look!

Copy link

@LinuxBozo LinuxBozo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@afeld afeld merged commit 03067f6 into master Sep 1, 2017
@afeld afeld deleted the persistent-volume branch September 1, 2017 20:45
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants