diff --git a/README.md b/README.md index c92d6dc7b3209..4cd6f99261cde 100644 --- a/README.md +++ b/README.md @@ -137,38 +137,11 @@ Each file in the tree describes a Task. On the nodeup side, Tasks can manage files, systemd services, packages etc. On the `kops update cluster` side, Tasks manage cloud resources: instances, networks, disks etc. -## Workaround for terraform bug +## Generate a terraform configuration -Terraform currently has a bug where it can't create AWS tags containing a dot. Until this is fixed, -you can't use terraform to build EC2 resources that are tagged with `k8s.io/...` tags. Thankfully this is only -the volumes, and it isn't the worst idea to build these separately anyway. +Kops can also generate a terraform configuration, which you can then apply using terraform, to build a Kubernetes +cluster using terraform. -We divide the cloudup model into three parts: -* models/config which contains all the options - this is run automatically by "create cluster" -* models/proto which sets up the volumes and other data which would be hard to recover (e.g. likely keys & secrets in the near future) -* models/cloudup which is the main cloud model for configuring everything else +If you are using a version of terraform prior to 0.7, please read about the [workaround for earlier versions of terraform](docs/terraform.md). -So you don't use terraform for the 'proto' phase (you can't anyway, because of the bug!): - -``` -export KOPS_STATE_STORE=s3:// -export NAME= -${GOPATH}/bin/kops create cluster --v=0 --zones=us-east-1c ${NAME} -${GOPATH}/bin/kops update cluster --v=0 ${NAME} --model=proto --yes -``` - -And then you can use terraform to do the remainder of the installation: - -``` -export CLUSTER_NAME= -${GOPATH}/bin/kops update cluster --v=0 ${NAME} --model=cloudup --target=terraform -``` - -Then, to apply using terraform: - -``` -cd out/terraform - -terraform plan -terraform apply -``` +For more details, please read the [how to use terraform to create a Kubernetes cluster](docs/terraform.md) diff --git a/docs/terraform.md b/docs/terraform.md new file mode 100644 index 0000000000000..3e2071b60eacf --- /dev/null +++ b/docs/terraform.md @@ -0,0 +1,71 @@ +## Building Kubernetes clusters with terraform + +Kops can generate terraform configurations, and you can then apply them using the terraform plan/apply tools. +This is very handy if you are already using terraform, or if you want to check in the terraform output into +version control. + +The terraform output should be reasonably stable (i.e. the text files should only change where something has actually +changed - items should appear in the same order etc). + + +### Using terraform + +To use terraform, you simple run update with `--target=terraform` (but see below for a workaround for a bug +if you are using a terraform version before 0.7) + +For example, a complete setup might be: + +``` +export KOPS_STATE_STORE=s3:// +export CLUSTER_NAME= +${GOPATH}/bin/kops create cluster ${NAME} --zones us-east-1c +${GOPATH}/bin/kops update cluster ${NAME} --target=terraform + +cd out/terraform +terraform plan +terraform aply +``` + + +### Workaround for Terraform versions before 0.7 + +Before terraform version 0.7, there was a bug where it could not create AWS tags containing a dot. + +We recommend upgrading to version 0.7 or laster, which wil fix this bug. + +However, if you need to use an earlier version: + +This issue only affects the volumes. + +We divide the cloudup model into three parts: +* models/config which contains all the options - this is run automatically by "create cluster" +* models/proto which sets up the volumes and other data which would be hard to recover (e.g. likely keys & secrets in the near future) +* models/cloudup which is the main cloud model for configuring everything else + +So the workaround is that you don't use terraform for the 'proto' phase (you can't anyway, because of the bug!): + +``` +export KOPS_STATE_STORE=s3:// +export CLUSTER_NAME= +${GOPATH}/bin/kops create cluster ${CLUSTER_NAME} --zones=us-east-1c +${GOPATH}/bin/kops update cluster ${CLUSTER_NAME} --model=proto --yes +``` + +And then you can use terraform to do the remainder of the installation: + +``` +export CLUSTER_NAME= +${GOPATH}/bin/kops update cluster ${CLUSTER_NAME} --model=cloudup --target=terraform +``` + +Then, to apply using terraform: + +``` +cd out/terraform + +terraform plan +terraform apply +``` + +Note that if you do this, you should still run `kops delete cluster ${CLUSTER_NAME}`, to remove the volumes +and the kops cluster specification. \ No newline at end of file diff --git a/upup/pkg/fi/cloudup/awstasks/sshkey.go b/upup/pkg/fi/cloudup/awstasks/sshkey.go index b40f2803bc71e..27c2f6327affe 100644 --- a/upup/pkg/fi/cloudup/awstasks/sshkey.go +++ b/upup/pkg/fi/cloudup/awstasks/sshkey.go @@ -230,7 +230,8 @@ type terraformSSHKey struct { } func (_ *SSHKey) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *SSHKey) error { - publicKey, err := t.AddFile("aws_key_pair", *e.Name, "public_key", e.PublicKey) + tfName := strings.Replace(*e.Name, ":", "", -1) + publicKey, err := t.AddFile("aws_key_pair", tfName, "public_key", e.PublicKey) if err != nil { return fmt.Errorf("error rendering PublicKey: %v", err) } @@ -240,9 +241,10 @@ func (_ *SSHKey) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *SS PublicKey: publicKey, } - return t.RenderResource("aws_key_pair", *e.Name, tf) + return t.RenderResource("aws_key_pair", tfName, tf) } func (e *SSHKey) TerraformLink() *terraform.Literal { - return terraform.LiteralProperty("aws_key_pair", *e.Name, "id") + tfName := strings.Replace(*e.Name, ":", "", -1) + return terraform.LiteralProperty("aws_key_pair", tfName, "id") }