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

Draft: Add InjectedIdentity for AWS Provider #294

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion bin/.gitignore

This file was deleted.

Binary file removed bin/terraform
Binary file not shown.
4 changes: 3 additions & 1 deletion controllers/configuration_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ const (
ClusterRoleName = "tf-executor-clusterrole"
// ServiceAccountName is the name of the ServiceAccount for Terraform Job
ServiceAccountName = "tf-executor-service-account"
// ArnRoleName is the name of the ARN annotated in ServiceAccount for Terraform Job
arnrolename = "arn:aws:iam::001122334455:role/terraform-controller-sa"
)

// ConfigurationReconciler reconciles a Configuration object.
Expand Down Expand Up @@ -603,7 +605,7 @@ func (meta *TFConfigurationMeta) updateDestroyStatus(ctx context.Context, k8sCli

func (meta *TFConfigurationMeta) assembleAndTriggerJob(ctx context.Context, k8sClient client.Client, executionType TerraformExecutionType) error {
// apply rbac
if err := createTerraformExecutorServiceAccount(ctx, k8sClient, meta.Namespace, ServiceAccountName); err != nil {
if err := createTerraformExecutorServiceAccount(ctx, k8sClient, meta.Namespace, ServiceAccountName, arnrolename); err != nil {
return err
}
if err := createTerraformExecutorClusterRoleBinding(ctx, k8sClient, meta.Namespace, fmt.Sprintf("%s-%s", meta.Namespace, ClusterRoleName), ServiceAccountName); err != nil {
Expand Down
35 changes: 31 additions & 4 deletions controllers/provider/aws.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package provider

import (
"os"

"github.com/pkg/errors"
"gopkg.in/yaml.v2"
"k8s.io/klog/v2"
)

const (
envAWSAccessKeyID = "AWS_ACCESS_KEY_ID"
envAWSSecretAccessKey = "AWS_SECRET_ACCESS_KEY"
envAWSDefaultRegion = "AWS_DEFAULT_REGION"
envAWSSessionToken = "AWS_SESSION_TOKEN"
envAWSAccessKeyID = "AWS_ACCESS_KEY_ID"
envAWSSecretAccessKey = "AWS_SECRET_ACCESS_KEY"
envAWSDefaultRegion = "AWS_DEFAULT_REGION"
envAWSSessionToken = "AWS_SESSION_TOKEN"
envAWSRoleArn = "AWS_ROLE_ARN"
envAWSWebIdentityTokenFile = "AWS_WEB_IDENTITY_TOKEN_FILE"
)

// AWSCredentials are credentials for AWS
Expand All @@ -20,6 +24,11 @@ type AWSCredentials struct {
AWSSessionToken string `yaml:"awsSessionToken"`
}

type AWSCredentialsInjected struct {
AWSRoleArn string `env:"AWS_ROLE_ARN"`
AWSWebIdentityTokenFile string `env:"AWS_WEB_IDENTITY_TOKEN_FILE"`
}

func getAWSCredentials(secretData []byte, name, namespace, region string) (map[string]string, error) {
var ak AWSCredentials
if err := yaml.Unmarshal(secretData, &ak); err != nil {
Expand All @@ -33,3 +42,21 @@ func getAWSCredentials(secretData []byte, name, namespace, region string) (map[s
envAWSDefaultRegion: region,
}, nil
}

func getAWSCredentialsInjectedIdentity(region string) (map[string]string, error) {
// var ak AWSCredentialsInjected
// opts := &ak.Options{Environment: map[string]string{
// "AWS_ROLE_ARN": "arn:aws:iam::001122334455:role/terrafrom-controller-sa",
// "AWS_WEB_IDENTITY_TOKEN_FILE": "/var/run/secrets/eks.amazonaws.com/serviceaccount/token",
// }}
arn := os.Getenv("AWS_ROLE_ARN")
token := os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE")

return map[string]string{
// envAWSRoleArn: ak.AWSRoleArn, //os.Getenv("AWS_ROLE_ARN"),
// envAWSWebIdentityTokenFile: ak.AWSWebIdentityTokenFile, //os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE"),
envAWSRoleArn: arn,
envAWSWebIdentityTokenFile: token,
envAWSDefaultRegion: region,
}, nil
}
5 changes: 5 additions & 0 deletions controllers/provider/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,17 @@ func GetProviderCredentials(ctx context.Context, k8sClient client.Client, provid
klog.InfoS(errMsg, "Provider", provider.Spec.Provider)
return nil, errors.New(errMsg)
}
case "InjectedIdentity":
if provider.Spec.Provider == "aws" {
return getAWSCredentialsInjectedIdentity(region)
}
default:
errMsg := "the credentials type is not supported."
err := errors.New(errMsg)
klog.ErrorS(err, "", "CredentialType", provider.Spec.Credentials.Source)
return nil, err
}
return nil, nil
}

// GetProviderFromConfiguration gets provider object from Configuration
Expand Down
25 changes: 25 additions & 0 deletions controllers/provider/credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,15 @@ func TestGetProviderCredentials4AWS(t *testing.T) {
},
}

provider2 := v1beta1.Provider{
Spec: v1beta1.ProviderSpec{
Provider: string(aws),
Credentials: v1beta1.ProviderCredentials{
Source: "InjectedIdentity",
},
},
}

secret2 := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "wrong-data",
Expand All @@ -1025,6 +1034,9 @@ func TestGetProviderCredentials4AWS(t *testing.T) {
k8sClient2 := fake.NewClientBuilder().Build()
assert.Nil(t, k8sClient2.Create(ctx, secret2))

// k8sClient3 := fake.NewClientBuilder().Build()
// assert.Nil(t, k8sClient2.Create(ctx, &provider2))

var badProvider v1beta1.Provider
copier.CopyWithOption(&badProvider, &provider, copier.Option{DeepCopy: true})
badProvider.Spec.Credentials.SecretRef.Name = "wrong-data"
Expand Down Expand Up @@ -1054,6 +1066,19 @@ func TestGetProviderCredentials4AWS(t *testing.T) {
envAWSDefaultRegion: "bj",
},
},
{
name: "provider with injectd identity",
args: args{
k8sClient: k8sClient,
provider: provider2,
region: "bj",
},
want: map[string]string{
envAWSRoleArn: "",
envAWSWebIdentityTokenFile: "",
envAWSDefaultRegion: "bj",
},
},
{
name: "provider with wrong data",
args: args{
Expand Down
6 changes: 5 additions & 1 deletion controllers/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func createTerraformExecutorClusterRoleBinding(ctx context.Context, k8sClient cl
return nil
}

func createTerraformExecutorServiceAccount(ctx context.Context, k8sClient client.Client, namespace, serviceAccountName string) error {
func createTerraformExecutorServiceAccount(ctx context.Context, k8sClient client.Client, namespace, serviceAccountName string, arnrolename string) error {
var serviceAccount = v1.ServiceAccount{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Expand All @@ -87,6 +87,10 @@ func createTerraformExecutorServiceAccount(ctx context.Context, k8sClient client
ObjectMeta: metav1.ObjectMeta{
Name: serviceAccountName,
Namespace: namespace,
Annotations: map[string]string{
// This annotation inject iam role for pod
"eks.amazonaws.com/role-arn": arnrolename,
},
},
}
if err := k8sClient.Get(ctx, client.ObjectKey{Name: serviceAccountName, Namespace: namespace}, &v1.ServiceAccount{}); err != nil {
Expand Down
10 changes: 10 additions & 0 deletions examples/aws/provider injected.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: terraform.core.oam.dev/v1beta1
kind: Provider
metadata:
name: aws
spec:
provider: aws
region: us-east-1
credentials:
source: InjectedIdentity