mirror of https://github.com/kubernetes/kops.git
Add External Policies (AWS managed policy attachments)
This commit is contained in:
parent
fd99b3b42f
commit
f025ff0e70
|
@ -33,6 +33,7 @@ type MockIAM struct {
|
|||
InstanceProfiles map[string]*iam.InstanceProfile
|
||||
Roles map[string]*iam.Role
|
||||
RolePolicies []*rolePolicy
|
||||
AttachedPolicies map[string][]*iam.AttachedPolicy
|
||||
}
|
||||
|
||||
var _ iamiface.IAMAPI = &MockIAM{}
|
||||
|
|
|
@ -141,9 +141,47 @@ func (m *MockIAM) DeleteRole(request *iam.DeleteRoleInput) (*iam.DeleteRoleOutpu
|
|||
|
||||
return &iam.DeleteRoleOutput{}, nil
|
||||
}
|
||||
|
||||
func (m *MockIAM) DeleteRoleWithContext(aws.Context, *iam.DeleteRoleInput, ...request.Option) (*iam.DeleteRoleOutput, error) {
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
func (m *MockIAM) DeleteRoleRequest(*iam.DeleteRoleInput) (*request.Request, *iam.DeleteRoleOutput) {
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
func (m *MockIAM) ListAttachedRolePolicies(input *iam.ListAttachedRolePoliciesInput) (*iam.ListAttachedRolePoliciesOutput, error) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
klog.Infof("ListAttachedRolePolicies: %s", aws.StringValue(input.RoleName))
|
||||
|
||||
for _, r := range m.Roles {
|
||||
if r.RoleName == input.RoleName {
|
||||
role := aws.StringValue(r.RoleName)
|
||||
|
||||
return &iam.ListAttachedRolePoliciesOutput{
|
||||
AttachedPolicies: m.AttachedPolicies[role],
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &iam.ListAttachedRolePoliciesOutput{}, nil
|
||||
}
|
||||
|
||||
func (m *MockIAM) ListAttachedRolePoliciesPages(input *iam.ListAttachedRolePoliciesInput, pager func(*iam.ListAttachedRolePoliciesOutput, bool) bool) error {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
klog.Infof("ListAttachedRolePolicies: %s", aws.StringValue(input.RoleName))
|
||||
|
||||
role := aws.StringValue(input.RoleName)
|
||||
|
||||
if pager(&iam.ListAttachedRolePoliciesOutput{
|
||||
AttachedPolicies: m.AttachedPolicies[role],
|
||||
}, true) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -82,6 +82,11 @@ func TestComplex(t *testing.T) {
|
|||
runTestCloudformation(t, "complex.example.com", "complex", "v1alpha2", false, nil, true)
|
||||
}
|
||||
|
||||
// TestExternalPolicies tests external policies output
|
||||
func TestExternalPolicies(t *testing.T) {
|
||||
runTestAWS(t, "externalpolicies.example.com", "externalpolicies", "v1alpha2", false, 1, true, false, nil, true, false)
|
||||
}
|
||||
|
||||
func TestNoSSHKey(t *testing.T) {
|
||||
runTestAWS(t, "nosshkey.example.com", "nosshkey", "v1alpha2", false, 1, true, false, nil, false, false)
|
||||
}
|
||||
|
|
|
@ -57,6 +57,26 @@ The additional permissions are:
|
|||
}
|
||||
```
|
||||
|
||||
## Adding External Policies
|
||||
|
||||
At times you may want to attach policies shared to you by another AWS account or that are maintained by an outside application. You can specify managed policies through the `policyOverrides` spec field.
|
||||
|
||||
Policy Overrides are specified by their ARN on AWS and are grouped by their role type. See the example below:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
externalPolicies:
|
||||
node:
|
||||
- aws:arn:iam:123456789000:policy:test-policy
|
||||
master:
|
||||
- aws:arn:iam:123456789000:policy:test-policy
|
||||
bastion:
|
||||
- aws:arn:iam:123456789000:policy:test-policy
|
||||
```
|
||||
|
||||
External Policy attachments are treated declaritively. Any policies declared will be attached to the role, any policies not specified will be detached _after_ new policies are attached. This does not replace or affect built in Kops policies in any way.
|
||||
|
||||
It's important to note that externalPolicies will only handle the attachment and detachment of policies, not creation, modification, or deletion.
|
||||
|
||||
## Adding Additional Policies
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
. $(dirname "${BASH_SOURCE}")/common.sh
|
||||
|
||||
WORK_DIR=`mktemp -d`
|
||||
WORK_DIR=$(mktemp -d)
|
||||
|
||||
cleanup() {
|
||||
chmod -R +w "${WORK_DIR}"
|
||||
|
@ -26,19 +26,19 @@ cleanup() {
|
|||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
mkdir -p ${WORK_DIR}/go/
|
||||
ln -s ${GOPATH}/src/k8s.io/kops/vendor/ ${WORK_DIR}/go/src
|
||||
mkdir -p "${WORK_DIR}/go/"
|
||||
cp -R "${GOPATH}/src/k8s.io/kops/vendor/" "${WORK_DIR}/go/src"
|
||||
|
||||
unset GOBIN
|
||||
GOPATH=${WORK_DIR}/go/ go install -v k8s.io/code-generator/cmd/conversion-gen/
|
||||
cp ${WORK_DIR}/go/bin/conversion-gen ${GOPATH}/bin/
|
||||
|
||||
GOPATH=${WORK_DIR}/go/ go install k8s.io/code-generator/cmd/deepcopy-gen/
|
||||
cp ${WORK_DIR}/go/bin/deepcopy-gen ${GOPATH}/bin/
|
||||
env GOBIN="${WORK_DIR}/go/bin" GOPATH="${WORK_DIR}/go/" go install -v k8s.io/code-generator/cmd/conversion-gen/
|
||||
cp "${WORK_DIR}/go/bin/conversion-gen" "${GOPATH}/bin/"
|
||||
|
||||
GOPATH=${WORK_DIR}/go/ go install k8s.io/code-generator/cmd/defaulter-gen/
|
||||
cp ${WORK_DIR}/go/bin/defaulter-gen ${GOPATH}/bin/
|
||||
env GOBIN="${WORK_DIR}/go/bin" GOPATH="${WORK_DIR}/go/" go install k8s.io/code-generator/cmd/deepcopy-gen/
|
||||
cp "${WORK_DIR}/go/bin/deepcopy-gen" "${GOPATH}/bin/"
|
||||
|
||||
GOPATH=${WORK_DIR}/go/ go install k8s.io/code-generator/cmd/client-gen/
|
||||
cp ${WORK_DIR}/go/bin/client-gen ${GOPATH}/bin/
|
||||
env GOBIN="${WORK_DIR}/go/bin" GOPATH="${WORK_DIR}/go/" go install k8s.io/code-generator/cmd/defaulter-gen/
|
||||
cp "${WORK_DIR}/go/bin/defaulter-gen" "${GOPATH}/bin/"
|
||||
|
||||
env GOBIN="${WORK_DIR}/go/bin" GOPATH="${WORK_DIR}/go/" go install k8s.io/code-generator/cmd/client-gen/
|
||||
cp "${WORK_DIR}/go/bin/client-gen" "${GOPATH}/bin/"
|
|
@ -670,6 +670,14 @@ spec:
|
|||
(use to control whom can creates dns entries)
|
||||
type: string
|
||||
type: object
|
||||
externalPolicies:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
description: ExternalPolicies allows the insertion of pre-existing managed
|
||||
policies on IG Roles
|
||||
type: object
|
||||
fileAssets:
|
||||
description: A collection of files assets for deployed cluster wide
|
||||
items:
|
||||
|
|
|
@ -136,6 +136,8 @@ type ClusterSpec struct {
|
|||
// 'external' do not apply updates automatically - they are applied manually or by an external system
|
||||
// missing: default policy (currently OS security upgrades that do not require a reboot)
|
||||
UpdatePolicy *string `json:"updatePolicy,omitempty"`
|
||||
// ExternalPolicies allows the insertion of pre-existing managed policies on IG Roles
|
||||
ExternalPolicies *map[string][]string `json:"externalPolicies,omitempty"`
|
||||
// Additional policies to add for roles
|
||||
AdditionalPolicies *map[string]string `json:"additionalPolicies,omitempty"`
|
||||
// A collection of files assets for deployed cluster wide
|
||||
|
|
|
@ -130,6 +130,8 @@ type ClusterSpec struct {
|
|||
// 'external' do not apply updates automatically - they are applied manually or by an external system
|
||||
// missing: default policy (currently OS security upgrades that do not require a reboot)
|
||||
UpdatePolicy *string `json:"updatePolicy,omitempty"`
|
||||
// ExternalPolicies allows the insertion of pre-existing managed policies on IG Roles
|
||||
ExternalPolicies *map[string][]string `json:"externalPolicies,omitempty"`
|
||||
// Additional policies to add for roles
|
||||
AdditionalPolicies *map[string]string `json:"additionalPolicies,omitempty"`
|
||||
// A collection of files assets for deployed cluster wide
|
||||
|
|
|
@ -1674,6 +1674,7 @@ func autoConvert_v1alpha1_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out *
|
|||
// WARNING: in.AdminAccess requires manual conversion: does not exist in peer-type
|
||||
out.IsolateMasters = in.IsolateMasters
|
||||
out.UpdatePolicy = in.UpdatePolicy
|
||||
out.ExternalPolicies = in.ExternalPolicies
|
||||
out.AdditionalPolicies = in.AdditionalPolicies
|
||||
if in.FileAssets != nil {
|
||||
in, out := &in.FileAssets, &out.FileAssets
|
||||
|
@ -1991,6 +1992,7 @@ func autoConvert_kops_ClusterSpec_To_v1alpha1_ClusterSpec(in *kops.ClusterSpec,
|
|||
// WARNING: in.KubernetesAPIAccess requires manual conversion: does not exist in peer-type
|
||||
out.IsolateMasters = in.IsolateMasters
|
||||
out.UpdatePolicy = in.UpdatePolicy
|
||||
out.ExternalPolicies = in.ExternalPolicies
|
||||
out.AdditionalPolicies = in.AdditionalPolicies
|
||||
if in.FileAssets != nil {
|
||||
in, out := &in.FileAssets, &out.FileAssets
|
||||
|
|
|
@ -651,6 +651,25 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
|||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ExternalPolicies != nil {
|
||||
in, out := &in.ExternalPolicies, &out.ExternalPolicies
|
||||
*out = new(map[string][]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string][]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.AdditionalPolicies != nil {
|
||||
in, out := &in.AdditionalPolicies, &out.AdditionalPolicies
|
||||
*out = new(map[string]string)
|
||||
|
|
|
@ -135,6 +135,8 @@ type ClusterSpec struct {
|
|||
// 'external' do not apply updates automatically - they are applied manually or by an external system
|
||||
// missing: default policy (currently OS security upgrades that do not require a reboot)
|
||||
UpdatePolicy *string `json:"updatePolicy,omitempty"`
|
||||
// ExternalPolicies allows the insertion of pre-existing managed policies on IG Roles
|
||||
ExternalPolicies *map[string][]string `json:"externalPolicies,omitempty"`
|
||||
// Additional policies to add for roles
|
||||
AdditionalPolicies *map[string]string `json:"additionalPolicies,omitempty"`
|
||||
// A collection of files assets for deployed cluster wide
|
||||
|
|
|
@ -1737,6 +1737,7 @@ func autoConvert_v1alpha2_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out *
|
|||
out.KubernetesAPIAccess = in.KubernetesAPIAccess
|
||||
out.IsolateMasters = in.IsolateMasters
|
||||
out.UpdatePolicy = in.UpdatePolicy
|
||||
out.ExternalPolicies = in.ExternalPolicies
|
||||
out.AdditionalPolicies = in.AdditionalPolicies
|
||||
if in.FileAssets != nil {
|
||||
in, out := &in.FileAssets, &out.FileAssets
|
||||
|
@ -2059,6 +2060,7 @@ func autoConvert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec,
|
|||
out.KubernetesAPIAccess = in.KubernetesAPIAccess
|
||||
out.IsolateMasters = in.IsolateMasters
|
||||
out.UpdatePolicy = in.UpdatePolicy
|
||||
out.ExternalPolicies = in.ExternalPolicies
|
||||
out.AdditionalPolicies = in.AdditionalPolicies
|
||||
if in.FileAssets != nil {
|
||||
in, out := &in.FileAssets, &out.FileAssets
|
||||
|
|
|
@ -634,6 +634,25 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
|||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ExternalPolicies != nil {
|
||||
in, out := &in.ExternalPolicies, &out.ExternalPolicies
|
||||
*out = new(map[string][]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string][]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.AdditionalPolicies != nil {
|
||||
in, out := &in.AdditionalPolicies, &out.AdditionalPolicies
|
||||
*out = new(map[string]string)
|
||||
|
|
|
@ -734,6 +734,25 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
|||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ExternalPolicies != nil {
|
||||
in, out := &in.ExternalPolicies, &out.ExternalPolicies
|
||||
*out = new(map[string][]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string][]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.AdditionalPolicies != nil {
|
||||
in, out := &in.AdditionalPolicies, &out.AdditionalPolicies
|
||||
*out = new(map[string]string)
|
||||
|
|
|
@ -165,6 +165,27 @@ func (b *IAMModelBuilder) buildIAMTasks(igRole kops.InstanceGroupRole, iamName s
|
|||
c.AddTask(iamInstanceProfileRole)
|
||||
}
|
||||
|
||||
// Create External Policy tasks
|
||||
{
|
||||
var externalPolicies []string
|
||||
|
||||
if b.Cluster.Spec.ExternalPolicies != nil {
|
||||
p := *(b.Cluster.Spec.ExternalPolicies)
|
||||
externalPolicies = append(externalPolicies, p[strings.ToLower(string(igRole))]...)
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("%s-policyoverride", strings.ToLower(string(igRole)))
|
||||
t := &awstasks.IAMRolePolicy{
|
||||
Name: s(name),
|
||||
Lifecycle: b.Lifecycle,
|
||||
Role: iamRole,
|
||||
Managed: true,
|
||||
ExternalPolicies: &externalPolicies,
|
||||
}
|
||||
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
||||
// Generate additional policies if needed, and attach to existing role
|
||||
{
|
||||
additionalPolicy := ""
|
||||
|
|
|
@ -1889,11 +1889,13 @@ func ListRoute53Records(cloud fi.Cloud, clusterName string) ([]*resources.Resour
|
|||
}
|
||||
|
||||
func DeleteIAMRole(cloud fi.Cloud, r *resources.Resource) error {
|
||||
c := cloud.(awsup.AWSCloud)
|
||||
var attachedPolicies []*iam.AttachedPolicy
|
||||
var policyNames []string
|
||||
|
||||
c := cloud.(awsup.AWSCloud)
|
||||
roleName := r.Name
|
||||
|
||||
var policyNames []string
|
||||
// List Inline policies
|
||||
{
|
||||
request := &iam.ListRolePoliciesInput{
|
||||
RoleName: aws.String(roleName),
|
||||
|
@ -1914,6 +1916,26 @@ func DeleteIAMRole(cloud fi.Cloud, r *resources.Resource) error {
|
|||
}
|
||||
}
|
||||
|
||||
// List Attached Policies
|
||||
{
|
||||
request := &iam.ListAttachedRolePoliciesInput{
|
||||
RoleName: aws.String(roleName),
|
||||
}
|
||||
err := c.IAM().ListAttachedRolePoliciesPages(request, func(page *iam.ListAttachedRolePoliciesOutput, lastPage bool) bool {
|
||||
attachedPolicies = append(attachedPolicies, page.AttachedPolicies...)
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
if awsup.AWSErrorCode(err) == "NoSuchEntity" {
|
||||
klog.V(2).Infof("Got NoSuchEntity describing IAM RolePolicy %q; will treat as already-detached", roleName)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("error listing IAM role policies for %q: %v", roleName, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete inline policies
|
||||
for _, policyName := range policyNames {
|
||||
klog.V(2).Infof("Deleting IAM role policy %q %q", roleName, policyName)
|
||||
request := &iam.DeleteRolePolicyInput{
|
||||
|
@ -1926,6 +1948,20 @@ func DeleteIAMRole(cloud fi.Cloud, r *resources.Resource) error {
|
|||
}
|
||||
}
|
||||
|
||||
// Detach Managed Policies
|
||||
for _, policy := range attachedPolicies {
|
||||
klog.V(2).Infof("Deleting IAM role policy %q %q", roleName, policy)
|
||||
request := &iam.DetachRolePolicyInput{
|
||||
RoleName: aws.String(r.Name),
|
||||
PolicyArn: policy.PolicyArn,
|
||||
}
|
||||
_, err := c.IAM().DetachRolePolicy(request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error detaching IAM role policy %q %q: %v", roleName, *policy.PolicyArn, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete Role
|
||||
{
|
||||
klog.V(2).Infof("Deleting IAM role %q", r.Name)
|
||||
request := &iam.DeleteRoleInput{
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCtWu40XQo8dczLsCq0OWV+hxm9uV3WxeH9Kgh4sMzQxNtoU1pvW0XdjpkBesRKGoolfWeCLXWxpyQb1IaiMkKoz7MdhQ/6UKjMjP66aFWWp3pwD0uj0HuJ7tq4gKHKRYGTaZIRWpzUiANBrjugVgA+Sd7E/mYwc/DMXkIyRZbvhQ==
|
|
@ -0,0 +1,103 @@
|
|||
apiVersion: kops.k8s.io/v1alpha2
|
||||
kind: Cluster
|
||||
metadata:
|
||||
creationTimestamp: "2016-12-10T22:42:27Z"
|
||||
name: externalpolicies.example.com
|
||||
spec:
|
||||
api:
|
||||
loadBalancer:
|
||||
type: Public
|
||||
additionalSecurityGroups:
|
||||
- sg-exampleid3
|
||||
- sg-exampleid4
|
||||
kubernetesApiAccess:
|
||||
- 0.0.0.0/0
|
||||
channel: stable
|
||||
cloudProvider: aws
|
||||
cloudLabels:
|
||||
Owner: John Doe
|
||||
foo/bar: fib+baz
|
||||
configBase: memfs://clusters.example.com/externalpolicies.example.com
|
||||
etcdClusters:
|
||||
- etcdMembers:
|
||||
- instanceGroup: master-us-test-1a
|
||||
name: us-test-1a
|
||||
name: main
|
||||
- etcdMembers:
|
||||
- instanceGroup: master-us-test-1a
|
||||
name: us-test-1a
|
||||
name: events
|
||||
kubeAPIServer:
|
||||
serviceNodePortRange: 28000-32767
|
||||
auditWebhookBatchThrottleQps: 3.14
|
||||
kubernetesVersion: v1.14.0
|
||||
masterInternalName: api.internal.externalpolicies.example.com
|
||||
masterPublicName: api.externalpolicies.example.com
|
||||
networkCIDR: 172.20.0.0/16
|
||||
networking:
|
||||
kubenet: {}
|
||||
nodePortAccess:
|
||||
- 1.2.3.4/32
|
||||
- 10.20.30.0/24
|
||||
nonMasqueradeCIDR: 100.64.0.0/10
|
||||
sshAccess:
|
||||
- 0.0.0.0/0
|
||||
topology:
|
||||
masters: public
|
||||
nodes: public
|
||||
externalPolicies:
|
||||
node:
|
||||
- aws:arn:iam:123456789000:policy:test-policy
|
||||
master:
|
||||
- aws:arn:iam:123456789000:policy:test-policy
|
||||
bastion:
|
||||
- aws:arn:iam:123456789000:policy:test-policy
|
||||
subnets:
|
||||
- cidr: 172.20.32.0/19
|
||||
name: us-test-1a
|
||||
type: Public
|
||||
zone: us-test-1a
|
||||
|
||||
---
|
||||
|
||||
apiVersion: kops.k8s.io/v1alpha2
|
||||
kind: InstanceGroup
|
||||
metadata:
|
||||
creationTimestamp: "2016-12-10T22:42:28Z"
|
||||
name: nodes
|
||||
labels:
|
||||
kops.k8s.io/cluster: externalpolicies.example.com
|
||||
spec:
|
||||
additionalSecurityGroups:
|
||||
- sg-exampleid3
|
||||
- sg-exampleid4
|
||||
associatePublicIp: true
|
||||
suspendProcesses:
|
||||
- AZRebalance
|
||||
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
|
||||
machineType: t2.medium
|
||||
maxSize: 2
|
||||
minSize: 2
|
||||
role: Node
|
||||
subnets:
|
||||
- us-test-1a
|
||||
detailedInstanceMonitoring: true
|
||||
|
||||
---
|
||||
|
||||
apiVersion: kops.k8s.io/v1alpha2
|
||||
kind: InstanceGroup
|
||||
metadata:
|
||||
creationTimestamp: "2016-12-10T22:42:28Z"
|
||||
name: master-us-test-1a
|
||||
labels:
|
||||
kops.k8s.io/cluster: externalpolicies.example.com
|
||||
spec:
|
||||
associatePublicIp: true
|
||||
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
|
||||
machineType: m3.medium
|
||||
maxSize: 1
|
||||
minSize: 1
|
||||
role: Master
|
||||
subnets:
|
||||
- us-test-1a
|
|
@ -0,0 +1,644 @@
|
|||
locals = {
|
||||
cluster_name = "externalpolicies.example.com"
|
||||
master_autoscaling_group_ids = ["${aws_autoscaling_group.master-us-test-1a-masters-externalpolicies-example-com.id}"]
|
||||
master_security_group_ids = ["${aws_security_group.masters-externalpolicies-example-com.id}"]
|
||||
masters_role_arn = "${aws_iam_role.masters-externalpolicies-example-com.arn}"
|
||||
masters_role_name = "${aws_iam_role.masters-externalpolicies-example-com.name}"
|
||||
node_autoscaling_group_ids = ["${aws_autoscaling_group.nodes-externalpolicies-example-com.id}"]
|
||||
node_security_group_ids = ["${aws_security_group.nodes-externalpolicies-example-com.id}", "sg-exampleid3", "sg-exampleid4"]
|
||||
node_subnet_ids = ["${aws_subnet.us-test-1a-externalpolicies-example-com.id}"]
|
||||
nodes_role_arn = "${aws_iam_role.nodes-externalpolicies-example-com.arn}"
|
||||
nodes_role_name = "${aws_iam_role.nodes-externalpolicies-example-com.name}"
|
||||
region = "us-test-1"
|
||||
route_table_public_id = "${aws_route_table.externalpolicies-example-com.id}"
|
||||
subnet_us-test-1a_id = "${aws_subnet.us-test-1a-externalpolicies-example-com.id}"
|
||||
vpc_cidr_block = "${aws_vpc.externalpolicies-example-com.cidr_block}"
|
||||
vpc_id = "${aws_vpc.externalpolicies-example-com.id}"
|
||||
}
|
||||
|
||||
output "cluster_name" {
|
||||
value = "externalpolicies.example.com"
|
||||
}
|
||||
|
||||
output "master_autoscaling_group_ids" {
|
||||
value = ["${aws_autoscaling_group.master-us-test-1a-masters-externalpolicies-example-com.id}"]
|
||||
}
|
||||
|
||||
output "master_security_group_ids" {
|
||||
value = ["${aws_security_group.masters-externalpolicies-example-com.id}"]
|
||||
}
|
||||
|
||||
output "masters_role_arn" {
|
||||
value = "${aws_iam_role.masters-externalpolicies-example-com.arn}"
|
||||
}
|
||||
|
||||
output "masters_role_name" {
|
||||
value = "${aws_iam_role.masters-externalpolicies-example-com.name}"
|
||||
}
|
||||
|
||||
output "node_autoscaling_group_ids" {
|
||||
value = ["${aws_autoscaling_group.nodes-externalpolicies-example-com.id}"]
|
||||
}
|
||||
|
||||
output "node_security_group_ids" {
|
||||
value = ["${aws_security_group.nodes-externalpolicies-example-com.id}", "sg-exampleid3", "sg-exampleid4"]
|
||||
}
|
||||
|
||||
output "node_subnet_ids" {
|
||||
value = ["${aws_subnet.us-test-1a-externalpolicies-example-com.id}"]
|
||||
}
|
||||
|
||||
output "nodes_role_arn" {
|
||||
value = "${aws_iam_role.nodes-externalpolicies-example-com.arn}"
|
||||
}
|
||||
|
||||
output "nodes_role_name" {
|
||||
value = "${aws_iam_role.nodes-externalpolicies-example-com.name}"
|
||||
}
|
||||
|
||||
output "region" {
|
||||
value = "us-test-1"
|
||||
}
|
||||
|
||||
output "route_table_public_id" {
|
||||
value = "${aws_route_table.externalpolicies-example-com.id}"
|
||||
}
|
||||
|
||||
output "subnet_us-test-1a_id" {
|
||||
value = "${aws_subnet.us-test-1a-externalpolicies-example-com.id}"
|
||||
}
|
||||
|
||||
output "vpc_cidr_block" {
|
||||
value = "${aws_vpc.externalpolicies-example-com.cidr_block}"
|
||||
}
|
||||
|
||||
output "vpc_id" {
|
||||
value = "${aws_vpc.externalpolicies-example-com.id}"
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = "us-test-1"
|
||||
}
|
||||
|
||||
resource "aws_autoscaling_attachment" "master-us-test-1a-masters-externalpolicies-example-com" {
|
||||
elb = "${aws_elb.api-externalpolicies-example-com.id}"
|
||||
autoscaling_group_name = "${aws_autoscaling_group.master-us-test-1a-masters-externalpolicies-example-com.id}"
|
||||
}
|
||||
|
||||
resource "aws_autoscaling_group" "master-us-test-1a-masters-externalpolicies-example-com" {
|
||||
name = "master-us-test-1a.masters.externalpolicies.example.com"
|
||||
launch_configuration = "${aws_launch_configuration.master-us-test-1a-masters-externalpolicies-example-com.id}"
|
||||
max_size = 1
|
||||
min_size = 1
|
||||
vpc_zone_identifier = ["${aws_subnet.us-test-1a-externalpolicies-example-com.id}"]
|
||||
|
||||
tag = {
|
||||
key = "KubernetesCluster"
|
||||
value = "externalpolicies.example.com"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "Name"
|
||||
value = "master-us-test-1a.masters.externalpolicies.example.com"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "Owner"
|
||||
value = "John Doe"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "foo/bar"
|
||||
value = "fib+baz"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "k8s.io/role/master"
|
||||
value = "1"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "kops.k8s.io/instancegroup"
|
||||
value = "master-us-test-1a"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
metrics_granularity = "1Minute"
|
||||
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
|
||||
}
|
||||
|
||||
resource "aws_autoscaling_group" "nodes-externalpolicies-example-com" {
|
||||
name = "nodes.externalpolicies.example.com"
|
||||
launch_configuration = "${aws_launch_configuration.nodes-externalpolicies-example-com.id}"
|
||||
max_size = 2
|
||||
min_size = 2
|
||||
vpc_zone_identifier = ["${aws_subnet.us-test-1a-externalpolicies-example-com.id}"]
|
||||
|
||||
tag = {
|
||||
key = "KubernetesCluster"
|
||||
value = "externalpolicies.example.com"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "Name"
|
||||
value = "nodes.externalpolicies.example.com"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "Owner"
|
||||
value = "John Doe"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "foo/bar"
|
||||
value = "fib+baz"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "k8s.io/role/node"
|
||||
value = "1"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
tag = {
|
||||
key = "kops.k8s.io/instancegroup"
|
||||
value = "nodes"
|
||||
propagate_at_launch = true
|
||||
}
|
||||
|
||||
metrics_granularity = "1Minute"
|
||||
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
|
||||
suspended_processes = ["AZRebalance"]
|
||||
}
|
||||
|
||||
resource "aws_ebs_volume" "us-test-1a-etcd-events-externalpolicies-example-com" {
|
||||
availability_zone = "us-test-1a"
|
||||
size = 20
|
||||
type = "gp2"
|
||||
encrypted = false
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "us-test-1a.etcd-events.externalpolicies.example.com"
|
||||
Owner = "John Doe"
|
||||
"foo/bar" = "fib+baz"
|
||||
"k8s.io/etcd/events" = "us-test-1a/us-test-1a"
|
||||
"k8s.io/role/master" = "1"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_ebs_volume" "us-test-1a-etcd-main-externalpolicies-example-com" {
|
||||
availability_zone = "us-test-1a"
|
||||
size = 20
|
||||
type = "gp2"
|
||||
encrypted = false
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "us-test-1a.etcd-main.externalpolicies.example.com"
|
||||
Owner = "John Doe"
|
||||
"foo/bar" = "fib+baz"
|
||||
"k8s.io/etcd/main" = "us-test-1a/us-test-1a"
|
||||
"k8s.io/role/master" = "1"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_elb" "api-externalpolicies-example-com" {
|
||||
name = "api-externalpolicies-exam-5cse45"
|
||||
|
||||
listener = {
|
||||
instance_port = 443
|
||||
instance_protocol = "TCP"
|
||||
lb_port = 443
|
||||
lb_protocol = "TCP"
|
||||
}
|
||||
|
||||
security_groups = ["${aws_security_group.api-elb-externalpolicies-example-com.id}", "sg-exampleid3", "sg-exampleid4"]
|
||||
subnets = ["${aws_subnet.us-test-1a-externalpolicies-example-com.id}"]
|
||||
|
||||
health_check = {
|
||||
target = "SSL:443"
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 2
|
||||
interval = 10
|
||||
timeout = 5
|
||||
}
|
||||
|
||||
cross_zone_load_balancing = false
|
||||
idle_timeout = 300
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "api.externalpolicies.example.com"
|
||||
Owner = "John Doe"
|
||||
"foo/bar" = "fib+baz"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "masters-externalpolicies-example-com" {
|
||||
name = "masters.externalpolicies.example.com"
|
||||
role = "${aws_iam_role.masters-externalpolicies-example-com.name}"
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "nodes-externalpolicies-example-com" {
|
||||
name = "nodes.externalpolicies.example.com"
|
||||
role = "${aws_iam_role.nodes-externalpolicies-example-com.name}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "masters-externalpolicies-example-com" {
|
||||
name = "masters.externalpolicies.example.com"
|
||||
assume_role_policy = "${file("${path.module}/data/aws_iam_role_masters.externalpolicies.example.com_policy")}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "nodes-externalpolicies-example-com" {
|
||||
name = "nodes.externalpolicies.example.com"
|
||||
assume_role_policy = "${file("${path.module}/data/aws_iam_role_nodes.externalpolicies.example.com_policy")}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "masters-externalpolicies-example-com" {
|
||||
name = "masters.externalpolicies.example.com"
|
||||
role = "${aws_iam_role.masters-externalpolicies-example-com.name}"
|
||||
policy = "${file("${path.module}/data/aws_iam_role_policy_masters.externalpolicies.example.com_policy")}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "nodes-externalpolicies-example-com" {
|
||||
name = "nodes.externalpolicies.example.com"
|
||||
role = "${aws_iam_role.nodes-externalpolicies-example-com.name}"
|
||||
policy = "${file("${path.module}/data/aws_iam_role_policy_nodes.externalpolicies.example.com_policy")}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy_attachment" "master-policyoverride-1178482798" {
|
||||
role = "${aws_iam_role.masters-externalpolicies-example-com.name}"
|
||||
policy_arn = "aws:arn:iam:123456789000:policy:test-policy"
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy_attachment" "node-policyoverride-1178482798" {
|
||||
role = "${aws_iam_role.nodes-externalpolicies-example-com.name}"
|
||||
policy_arn = "aws:arn:iam:123456789000:policy:test-policy"
|
||||
}
|
||||
|
||||
resource "aws_internet_gateway" "externalpolicies-example-com" {
|
||||
vpc_id = "${aws_vpc.externalpolicies-example-com.id}"
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "externalpolicies.example.com"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_key_pair" "kubernetes-externalpolicies-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157" {
|
||||
key_name = "kubernetes.externalpolicies.example.com-c4:a6:ed:9a:a8:89:b9:e2:c3:9c:d6:63:eb:9c:71:57"
|
||||
public_key = "${file("${path.module}/data/aws_key_pair_kubernetes.externalpolicies.example.com-c4a6ed9aa889b9e2c39cd663eb9c7157_public_key")}"
|
||||
}
|
||||
|
||||
resource "aws_launch_configuration" "master-us-test-1a-masters-externalpolicies-example-com" {
|
||||
name_prefix = "master-us-test-1a.masters.externalpolicies.example.com-"
|
||||
image_id = "ami-12345678"
|
||||
instance_type = "m3.medium"
|
||||
key_name = "${aws_key_pair.kubernetes-externalpolicies-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
|
||||
iam_instance_profile = "${aws_iam_instance_profile.masters-externalpolicies-example-com.id}"
|
||||
security_groups = ["${aws_security_group.masters-externalpolicies-example-com.id}"]
|
||||
associate_public_ip_address = true
|
||||
user_data = "${file("${path.module}/data/aws_launch_configuration_master-us-test-1a.masters.externalpolicies.example.com_user_data")}"
|
||||
|
||||
root_block_device = {
|
||||
volume_type = "gp2"
|
||||
volume_size = 64
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
ephemeral_block_device = {
|
||||
device_name = "/dev/sdc"
|
||||
virtual_name = "ephemeral0"
|
||||
}
|
||||
|
||||
lifecycle = {
|
||||
create_before_destroy = true
|
||||
}
|
||||
|
||||
enable_monitoring = false
|
||||
}
|
||||
|
||||
resource "aws_launch_configuration" "nodes-externalpolicies-example-com" {
|
||||
name_prefix = "nodes.externalpolicies.example.com-"
|
||||
image_id = "ami-12345678"
|
||||
instance_type = "t2.medium"
|
||||
key_name = "${aws_key_pair.kubernetes-externalpolicies-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
|
||||
iam_instance_profile = "${aws_iam_instance_profile.nodes-externalpolicies-example-com.id}"
|
||||
security_groups = ["${aws_security_group.nodes-externalpolicies-example-com.id}", "sg-exampleid3", "sg-exampleid4"]
|
||||
associate_public_ip_address = true
|
||||
user_data = "${file("${path.module}/data/aws_launch_configuration_nodes.externalpolicies.example.com_user_data")}"
|
||||
|
||||
root_block_device = {
|
||||
volume_type = "gp2"
|
||||
volume_size = 128
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
lifecycle = {
|
||||
create_before_destroy = true
|
||||
}
|
||||
|
||||
enable_monitoring = true
|
||||
}
|
||||
|
||||
resource "aws_route" "route-0-0-0-0--0" {
|
||||
route_table_id = "${aws_route_table.externalpolicies-example-com.id}"
|
||||
destination_cidr_block = "0.0.0.0/0"
|
||||
gateway_id = "${aws_internet_gateway.externalpolicies-example-com.id}"
|
||||
}
|
||||
|
||||
resource "aws_route53_record" "api-externalpolicies-example-com" {
|
||||
name = "api.externalpolicies.example.com"
|
||||
type = "A"
|
||||
|
||||
alias = {
|
||||
name = "${aws_elb.api-externalpolicies-example-com.dns_name}"
|
||||
zone_id = "${aws_elb.api-externalpolicies-example-com.zone_id}"
|
||||
evaluate_target_health = false
|
||||
}
|
||||
|
||||
zone_id = "/hostedzone/Z1AFAKE1ZON3YO"
|
||||
}
|
||||
|
||||
resource "aws_route_table" "externalpolicies-example-com" {
|
||||
vpc_id = "${aws_vpc.externalpolicies-example-com.id}"
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "externalpolicies.example.com"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
"kubernetes.io/kops/role" = "public"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "us-test-1a-externalpolicies-example-com" {
|
||||
subnet_id = "${aws_subnet.us-test-1a-externalpolicies-example-com.id}"
|
||||
route_table_id = "${aws_route_table.externalpolicies-example-com.id}"
|
||||
}
|
||||
|
||||
resource "aws_security_group" "api-elb-externalpolicies-example-com" {
|
||||
name = "api-elb.externalpolicies.example.com"
|
||||
vpc_id = "${aws_vpc.externalpolicies-example-com.id}"
|
||||
description = "Security group for api ELB"
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "api-elb.externalpolicies.example.com"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "masters-externalpolicies-example-com" {
|
||||
name = "masters.externalpolicies.example.com"
|
||||
vpc_id = "${aws_vpc.externalpolicies-example-com.id}"
|
||||
description = "Security group for masters"
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "masters.externalpolicies.example.com"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "nodes-externalpolicies-example-com" {
|
||||
name = "nodes.externalpolicies.example.com"
|
||||
vpc_id = "${aws_vpc.externalpolicies-example-com.id}"
|
||||
description = "Security group for nodes"
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "nodes.externalpolicies.example.com"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "all-master-to-master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
source_security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "all-master-to-node" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
source_security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "all-node-to-node" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
source_security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "api-elb-egress" {
|
||||
type = "egress"
|
||||
security_group_id = "${aws_security_group.api-elb-externalpolicies-example-com.id}"
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "https-api-elb-0-0-0-0--0" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.api-elb-externalpolicies-example-com.id}"
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "https-elb-to-master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
source_security_group_id = "${aws_security_group.api-elb-externalpolicies-example-com.id}"
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
protocol = "tcp"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "icmp-pmtu-api-elb-0-0-0-0--0" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.api-elb-externalpolicies-example-com.id}"
|
||||
from_port = 3
|
||||
to_port = 4
|
||||
protocol = "icmp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master-egress" {
|
||||
type = "egress"
|
||||
security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "node-egress" {
|
||||
type = "egress"
|
||||
security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "node-to-master-tcp-1-2379" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
source_security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 1
|
||||
to_port = 2379
|
||||
protocol = "tcp"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "node-to-master-tcp-2382-4000" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
source_security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 2382
|
||||
to_port = 4000
|
||||
protocol = "tcp"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "node-to-master-tcp-4003-65535" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
source_security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 4003
|
||||
to_port = 65535
|
||||
protocol = "tcp"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "node-to-master-udp-1-65535" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
source_security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 1
|
||||
to_port = 65535
|
||||
protocol = "udp"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "nodeport-tcp-external-to-node-1-2-3-4--32" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 28000
|
||||
to_port = 32767
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["1.2.3.4/32"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "nodeport-tcp-external-to-node-10-20-30-0--24" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 28000
|
||||
to_port = 32767
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["10.20.30.0/24"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "nodeport-udp-external-to-node-1-2-3-4--32" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 28000
|
||||
to_port = 32767
|
||||
protocol = "udp"
|
||||
cidr_blocks = ["1.2.3.4/32"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "nodeport-udp-external-to-node-10-20-30-0--24" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 28000
|
||||
to_port = 32767
|
||||
protocol = "udp"
|
||||
cidr_blocks = ["10.20.30.0/24"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "ssh-external-to-master-0-0-0-0--0" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.masters-externalpolicies-example-com.id}"
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "ssh-external-to-node-0-0-0-0--0" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.nodes-externalpolicies-example-com.id}"
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_subnet" "us-test-1a-externalpolicies-example-com" {
|
||||
vpc_id = "${aws_vpc.externalpolicies-example-com.id}"
|
||||
cidr_block = "172.20.32.0/19"
|
||||
availability_zone = "us-test-1a"
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "us-test-1a.externalpolicies.example.com"
|
||||
SubnetType = "Public"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
"kubernetes.io/role/elb" = "1"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_vpc" "externalpolicies-example-com" {
|
||||
cidr_block = "172.20.0.0/16"
|
||||
enable_dns_hostnames = true
|
||||
enable_dns_support = true
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "externalpolicies.example.com"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_vpc_dhcp_options" "externalpolicies-example-com" {
|
||||
domain_name = "us-test-1.compute.internal"
|
||||
domain_name_servers = ["AmazonProvidedDNS"]
|
||||
|
||||
tags = {
|
||||
KubernetesCluster = "externalpolicies.example.com"
|
||||
Name = "externalpolicies.example.com"
|
||||
"kubernetes.io/cluster/externalpolicies.example.com" = "owned"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_vpc_dhcp_options_association" "externalpolicies-example-com" {
|
||||
vpc_id = "${aws_vpc.externalpolicies-example-com.id}"
|
||||
dhcp_options_id = "${aws_vpc_dhcp_options.externalpolicies-example-com.id}"
|
||||
}
|
||||
|
||||
terraform = {
|
||||
required_version = ">= 0.9.3"
|
||||
}
|
|
@ -18,6 +18,7 @@ package awstasks
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
@ -44,11 +45,49 @@ type IAMRolePolicy struct {
|
|||
// The PolicyDocument to create as an inline policy.
|
||||
// If the PolicyDocument is empty, the policy will be removed.
|
||||
PolicyDocument fi.Resource
|
||||
// External (non-kops managed) AWS policies to attach to the role
|
||||
ExternalPolicies *[]string
|
||||
// Managed tracks the use of ExternalPolicies
|
||||
Managed bool
|
||||
}
|
||||
|
||||
func (e *IAMRolePolicy) Find(c *fi.Context) (*IAMRolePolicy, error) {
|
||||
var actual IAMRolePolicy
|
||||
|
||||
cloud := c.Cloud.(awsup.AWSCloud)
|
||||
|
||||
// Handle policy overrides
|
||||
if e.ExternalPolicies != nil {
|
||||
request := &iam.ListAttachedRolePoliciesInput{
|
||||
RoleName: e.Role.Name,
|
||||
}
|
||||
|
||||
response, err := cloud.IAM().ListAttachedRolePolicies(request)
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
if awsErr.Code() == "NoSuchEntity" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("error getting policies for role: %v", err)
|
||||
}
|
||||
|
||||
var policies []string
|
||||
if response != nil && len(response.AttachedPolicies) > 0 {
|
||||
for _, policy := range response.AttachedPolicies {
|
||||
policies = append(policies, aws.StringValue(policy.PolicyArn))
|
||||
}
|
||||
}
|
||||
|
||||
actual.ID = e.ID
|
||||
actual.Name = e.Name
|
||||
actual.Lifecycle = e.Lifecycle
|
||||
actual.Role = e.Role
|
||||
actual.Managed = true
|
||||
actual.ExternalPolicies = &policies
|
||||
|
||||
return &actual, nil
|
||||
}
|
||||
|
||||
request := &iam.GetRolePolicyInput{
|
||||
RoleName: e.Role.Name,
|
||||
PolicyName: e.Name,
|
||||
|
@ -65,7 +104,6 @@ func (e *IAMRolePolicy) Find(c *fi.Context) (*IAMRolePolicy, error) {
|
|||
}
|
||||
|
||||
p := response
|
||||
actual := &IAMRolePolicy{}
|
||||
actual.Role = &IAMRole{Name: p.RoleName}
|
||||
if aws.StringValue(e.Role.Name) == aws.StringValue(p.RoleName) {
|
||||
actual.Role.ID = e.Role.ID
|
||||
|
@ -87,7 +125,7 @@ func (e *IAMRolePolicy) Find(c *fi.Context) (*IAMRolePolicy, error) {
|
|||
// Avoid spurious changes
|
||||
actual.Lifecycle = e.Lifecycle
|
||||
|
||||
return actual, nil
|
||||
return &actual, nil
|
||||
}
|
||||
|
||||
func (e *IAMRolePolicy) Run(c *fi.Context) error {
|
||||
|
@ -109,9 +147,10 @@ func (_ *IAMRolePolicy) ShouldCreate(a, e, changes *IAMRolePolicy) (bool, error)
|
|||
return false, fmt.Errorf("error rendering PolicyDocument: %v", err)
|
||||
}
|
||||
|
||||
if a == nil && ePolicy == "" {
|
||||
if a == nil && ePolicy == "" && e.ExternalPolicies == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
@ -121,6 +160,55 @@ func (_ *IAMRolePolicy) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *IAMRoleP
|
|||
return fmt.Errorf("error rendering PolicyDocument: %v", err)
|
||||
}
|
||||
|
||||
// Handles the full lifecycle of Policy Overrides
|
||||
if e.Managed {
|
||||
// Attach policies that are not already attached
|
||||
AttachPolicies:
|
||||
for _, policy := range *e.ExternalPolicies {
|
||||
for _, cloudPolicy := range *a.ExternalPolicies {
|
||||
if cloudPolicy == policy {
|
||||
continue AttachPolicies
|
||||
}
|
||||
}
|
||||
|
||||
request := &iam.AttachRolePolicyInput{
|
||||
RoleName: e.Role.Name,
|
||||
PolicyArn: s(policy),
|
||||
}
|
||||
|
||||
_, err = t.Cloud.IAM().AttachRolePolicy(request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error attaching IAMRolePolicy: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up unused cloud policies
|
||||
CheckPolicies:
|
||||
for _, cloudPolicy := range *a.ExternalPolicies {
|
||||
for _, policy := range *e.ExternalPolicies {
|
||||
if policy == cloudPolicy {
|
||||
continue CheckPolicies
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(2).Infof("Detaching unused IAMRolePolicy %s/%s", aws.StringValue(e.Role.Name), cloudPolicy)
|
||||
|
||||
// Detach policy
|
||||
request := &iam.DetachRolePolicyInput{
|
||||
RoleName: e.Role.Name,
|
||||
PolicyArn: s(cloudPolicy),
|
||||
}
|
||||
|
||||
_, err := t.Cloud.IAM().DetachRolePolicy(request)
|
||||
if err != nil {
|
||||
klog.V(2).Infof("Unable to detach IAMRolePolicy %s/%s", aws.StringValue(e.Role.Name), cloudPolicy)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if policy == "" {
|
||||
// A deletion
|
||||
|
||||
|
@ -192,12 +280,33 @@ func (e *IAMRolePolicy) policyDocumentString() (string, error) {
|
|||
}
|
||||
|
||||
type terraformIAMRolePolicy struct {
|
||||
Name *string `json:"name"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Role *terraform.Literal `json:"role"`
|
||||
PolicyDocument *terraform.Literal `json:"policy"`
|
||||
PolicyDocument *terraform.Literal `json:"policy,omitempty"`
|
||||
PolicyArn *string `json:"policy_arn,omitempty"`
|
||||
}
|
||||
|
||||
func (_ *IAMRolePolicy) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *IAMRolePolicy) error {
|
||||
if e.ExternalPolicies != nil && len(*e.ExternalPolicies) > 0 {
|
||||
for _, policy := range *e.ExternalPolicies {
|
||||
// create a hash of the arn
|
||||
h := fnv.New32a()
|
||||
h.Write([]byte(policy))
|
||||
|
||||
name := fmt.Sprintf("%s-%d", *e.Name, h.Sum32())
|
||||
|
||||
tf := &terraformIAMRolePolicy{
|
||||
Role: e.Role.TerraformLink(),
|
||||
PolicyArn: s(policy),
|
||||
}
|
||||
|
||||
err := t.RenderResource("aws_iam_role_policy_attachment", name, tf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error rendering RolePolicyAttachment: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
policyString, err := e.policyDocumentString()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error rendering PolicyDocument: %v", err)
|
||||
|
@ -233,6 +342,12 @@ type cloudformationIAMRolePolicy struct {
|
|||
}
|
||||
|
||||
func (_ *IAMRolePolicy) RenderCloudformation(t *cloudformation.CloudformationTarget, a, e, changes *IAMRolePolicy) error {
|
||||
// Currently CloudFormation does not have a reciprocal function to Terraform that allows the modification of a role
|
||||
// after the fact. In order to make this feature complete we would have to intercept the role task and modify it.
|
||||
if e.ExternalPolicies != nil && len(*e.ExternalPolicies) > 0 {
|
||||
return fmt.Errorf("CloudFormation not supported for use with ExternalPolicies.")
|
||||
}
|
||||
|
||||
policyString, err := e.policyDocumentString()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error rendering PolicyDocument: %v", err)
|
||||
|
|
Loading…
Reference in New Issue