diff --git a/.gitignore b/.gitignore index 41859c8..6a2a4e5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ # Module directory .terraform/ +.idea +*.iml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..241026e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +addons: + apt: + packages: + - git + - make + - curl + +install: + - make init + +script: + - make terraform/install + - make terraform/get-plugins + - make terraform/get-modules + - make terraform/lint + - make terraform/validate diff --git a/LICENSE b/LICENSE index 261eeb9..c37833f 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2018 Cloud Posse, LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d002c7d --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +SHELL := /bin/bash + +-include $(shell curl -sSL -o .build-harness "https://git.io/build-harness"; echo .build-harness) + +lint: + $(SELF) terraform/install terraform/get-modules terraform/get-plugins terraform/lint terraform/validate diff --git a/README.md b/README.md index de1eb75..8f67f7c 100644 --- a/README.md +++ b/README.md @@ -1 +1,132 @@ -# terraform-aws-kops-vault-backend \ No newline at end of file +# terraform-aws-kops-vault-backend [![Build Status](https://travis-ci.org/cloudposse/terraform-aws-kops-vault-backend.svg?branch=master)](https://travis-ci.org/cloudposse/terraform-aws-kops-vault-backend) + +Terraform module to provision an S3 bucket for [HashiCorp Vault](https://www.hashicorp.com/products/vault) secrets storage, and an IAM role and policy with permissions for Kops nodes to access the bucket. + +The module uses [terraform-aws-kops-metadata](https://github.com/cloudposse/terraform-aws-kops-metadata) to lookup resources within a Kops cluster for easier integration with Terraform. + + +## Usage + +```hcl +module "kops_vault_backend" { + source = "git::https://github.com/cloudposse/terraform-aws-kops-vault-backend.git?ref=master" + namespace = "cp" + stage = "prod" + name = "domain.com" + nodes_name = "nodes" + + tags = { + Cluster = "k8s.domain.com" + } +} +``` + + +## Variables + +| Name | Default | Description | Required | +|:-------------------|:-------------|:---------------------------------------------------------------------------------|:--------:| +| `namespace` | `` | Namespace (_e.g._ `cp` or `cloudposse`) | Yes | +| `stage` | `` | Stage (_e.g._ `prod`, `dev`, `staging`) | Yes | +| `name` | `` | Name of the Kops DNS zone (_e.g._ `domain.com`) | Yes | +| `attributes` | `[]` | Additional attributes (_e.g._ `1`) | No | +| `tags` | `{}` | Additional tags (_e.g._ `map("BusinessUnit","XYZ")` | No | +| `delimiter` | `-` | Delimiter to be used between `namespace`, `stage`, `name`, and `attributes` | No | +| `nodes_name` | `nodes` | Kops nodes subdomain name in the Kops DNS zone | No | + + +## Outputs + +| Name | Description | +|:-----------------------|:--------------------------| +| `bucket_domain_name` | S3 bucket domain name | +| `bucket_id` | S3 bucket ID | +| `bucket_arn` | S3 bucket ARN | +| `role_name` | IAM role name | +| `role_unique_id` | IAM role unique ID | +| `role_arn` | IAM role ARN | +| `policy_name` | IAM policy name | +| `policy_id` | IAM policy ID | +| `policy_arn` | IAM policy ARN | + + +## Help + +**Got a question?** + +File a GitHub [issue](https://github.com/cloudposse/terraform-aws-kops-vault-backend/issues), send us an [email](mailto:hello@cloudposse.com) or reach out to us on [Gitter](https://gitter.im/cloudposse/). + + +## Contributing + +### Bug Reports & Feature Requests + +Please use the [issue tracker](https://github.com/cloudposse/terraform-aws-kops-vault-backend/issues) to report any bugs or file feature requests. + +### Developing + +If you are interested in being a contributor and want to get involved in developing `terraform-aws-kops-vault-backend`, we would love to hear from you! Shoot us an [email](mailto:hello@cloudposse.com). + +In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. + + 1. **Fork** the repo on GitHub + 2. **Clone** the project to your own machine + 3. **Commit** changes to your own branch + 4. **Push** your work back up to your fork + 5. Submit a **Pull request** so that we can review your changes + +**NOTE:** Be sure to merge the latest from "upstream" before making a pull request! + + +## License + +[APACHE 2.0](LICENSE) © 2018 [Cloud Posse, LLC](https://cloudposse.com) + +See [LICENSE](LICENSE) for full details. + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. + + +## About + +`terraform-aws-kops-vault-backend` is maintained and funded by [Cloud Posse, LLC][website]. + +![Cloud Posse](https://cloudposse.com/logo-300x69.png) + + +Like it? Please let us know at + +We love [Open Source Software](https://github.com/cloudposse/)! + +See [our other projects][community] +or [hire us][hire] to help build your next cloud platform. + +[website]: https://cloudposse.com/ +[community]: https://github.com/cloudposse/ +[hire]: https://cloudposse.com/contact/ + + +## Contributors + +| [![Erik Osterman][erik_img]][erik_web]
[Erik Osterman][erik_web] | [![Andriy Knysh][andriy_img]][andriy_web]
[Andriy Knysh][andriy_web] | +|-------------------------------------------------------|------------------------------------------------------------------| + +[erik_img]: http://s.gravatar.com/avatar/88c480d4f73b813904e00a5695a454cb?s=144 +[erik_web]: https://github.com/osterman/ +[andriy_img]: https://avatars0.githubusercontent.com/u/7356997?v=4&u=ed9ce1c9151d552d985bdf5546772e14ef7ab617&s=144 +[andriy_web]: https://github.com/aknysh/ diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..ebbcd6e --- /dev/null +++ b/main.tf @@ -0,0 +1,101 @@ +module "label" { + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.3.3" + namespace = "${var.namespace}" + stage = "${var.stage}" + name = "${var.name}" + delimiter = "${var.delimiter}" + attributes = "${var.attributes}" + tags = "${var.tags}" +} + +module "kops_metadata" { + source = "git::https://github.com/cloudposse/terraform-aws-kops-metadata.git?ref=tags/0.1.1" + dns_zone = "${var.name}" + nodes_name = "${var.nodes_name}" +} + +resource "aws_s3_bucket" "default" { + bucket = "${module.label.id}" + acl = "private" + force_destroy = false + + tags = "${ + merge( + module.label.tags, + map( + "Description", "Used for secrets storage with Vault" + ) + ) + }" + + versioning { + enabled = true + } + + server_side_encryption_configuration { + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "AES256" + } + } + } +} + +data "aws_iam_policy_document" "default" { + statement { + actions = ["s3:ListBucket"] + resources = ["${aws_s3_bucket.default.arn}"] + effect = "Allow" + } + + statement { + actions = [ + "s3:DeleteObject", + "s3:GetObject", + "s3:PutObject", + ] + + resources = ["${aws_s3_bucket.default.arn}/*"] + effect = "Allow" + } +} + +resource "aws_iam_policy" "default" { + name = "${module.label.id}" + policy = "${data.aws_iam_policy_document.default.json}" + description = "Allow Vault to get/put/delete objects from the bucket" +} + +data "aws_iam_policy_document" "role_trust" { + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ec2.amazonaws.com"] + } + } + + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "AWS" + + identifiers = [ + "${module.kops_metadata.nodes_role_arn}", + ] + } + } +} + +resource "aws_iam_role" "default" { + name = "${module.label.id}" + assume_role_policy = "${data.aws_iam_policy_document.role_trust.json}" + description = "Allow Vault to get/put/delete objects from the bucket" +} + +resource "aws_iam_role_policy_attachment" "default" { + role = "${aws_iam_role.default.name}" + policy_arn = "${aws_iam_policy.default.arn}" +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..67501d4 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,35 @@ +output "bucket_domain_name" { + value = "${aws_s3_bucket.default.bucket_domain_name}" +} + +output "bucket_id" { + value = "${aws_s3_bucket.default.id}" +} + +output "bucket_arn" { + value = "${aws_s3_bucket.default.arn}" +} + +output "role_name" { + value = "${aws_iam_role.default.name}" +} + +output "role_unique_id" { + value = "${aws_iam_role.default.unique_id}" +} + +output "role_arn" { + value = "${aws_iam_role.default.arn}" +} + +output "policy_name" { + value = "${aws_iam_policy.default.name}" +} + +output "policy_id" { + value = "${aws_iam_policy.default.id}" +} + +output "policy_arn" { + value = "${aws_iam_policy.default.arn}" +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..41a757d --- /dev/null +++ b/variables.tf @@ -0,0 +1,38 @@ +variable "namespace" { + type = "string" + description = "Namespace (e.g. `cp` or `cloudposse`)" +} + +variable "stage" { + type = "string" + description = "Stage (e.g. `prod`, `dev`, `staging`)" +} + +variable "name" { + type = "string" + description = "Name of the Kops DNS zone (e.g. `domain.com`)" +} + +variable "delimiter" { + type = "string" + default = "-" + description = "Delimiter to be used between `namespace`, `stage`, `name`, and `attributes`" +} + +variable "attributes" { + type = "list" + default = [] + description = "Additional attributes (e.g. `1`)" +} + +variable "tags" { + type = "map" + default = {} + description = "Additional tags (e.g. map(`BusinessUnit`,`XYZ`)" +} + +variable "nodes_name" { + type = "string" + default = "nodes" + description = "Kops nodes subdomain name in the Kops DNS zone" +}