Skip to content

Commit

Permalink
OCPBUGS-15609: docs - add AWS CLI commands for STS instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
alebedev87 committed Sep 12, 2023
1 parent d1a1bb6 commit 791e160
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 25 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ manifests: ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefin
hack/sync-upstream-rbac.sh

.PHONY: generate
generate: iamctl-gen ## Generate code containing DeepCopy, DeepCopyInto, DeepCopyObject method implementations and iamctl policies.
generate: iamctl-gen iam-gen## Generate code containing DeepCopy, DeepCopyInto, DeepCopyObject method implementations and iamctl policies.
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

.PHONY: fmt
Expand All @@ -131,6 +131,10 @@ iamctl-gen: iamctl-build
go fmt -mod=vendor $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_FILE)
go vet -mod=vendor $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_FILE)

.PHONY: iam-gen
iam-gen:
./hack/generate-iam-from-credrequest.sh ./hack/operator-credentials-request.yaml ./hack/operator-permission-policy.json

ENVTEST_ASSETS_DIR ?= $(shell pwd)/bin

.PHONY: test
Expand Down
120 changes: 98 additions & 22 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,48 @@
This documents any required information either during installation or
post installation to ensure the operator can function correctly.

## STS Clusters

### Post operator installation
- [STS Clusters](#sts-clusters)
- [Post operator installation](#post-operator-installation)
- [Use CredentialsRequest created by the operator](#use-credentialsrequest-created-by-the-operator)
- [Use predefined secret](#use-predefined-secret)
- [Option 1. Using ccoctl](#option-1-using-ccoctl)
- [Option 2. Using AWS CLI](#option-2-using-the-aws-cli)

In an STS Cluster, `CredentialsRequest`s are not automatically provisioned by
the **cloud-credential-operator** and the manual intervention done by the
cluster-admin is required. IAM role and policies as well as the credentials secret need to be provisioned manually for the further consumption by the pods.
`ccoctl` binary can be used to facilitate this task.
## STS Clusters
In an STS cluster, the **cloud-credential-operator** does not automatically provision secrets for `CredentialsRequest`s,
so the cluster-admin must provision them manually.
IAM role and policies must also be provisioned manually.

Normally, the **aws-load-balancer-operator** relies on the **cloud-credential-operator**
to provision the secret for the operated controller using `CredentialsRequest`. And so in an STS cluster this
to provision the secret for the operated controller using `CredentialsRequest`. However, in an STS cluster this
secret needs to be provisioned manually. The **aws-load-balancer-operator** will wait until the required
secret is created and available before spawning the **aws-load-balancer-controller** pod.

#### Pre-Requisites
### Post operator installation

There are three ways to manually create the required IAM resources:
- Using a `CredentialsRequest` generated by the operator for an existing `AWSLoadBalancerController`.
- Using a pre-defined `CredentialsRequest` before `AWSLoadBalancerController` creation.
- Using pre-defined AWS manifests before `AWSLoadBalancerController` creation.

For handling `CredentialsRequests`, the cloud credential operator utility, [ccoctl](https://docs.openshift.com/container-platform/latest/authentication/managing_cloud_provider_credentials/cco-mode-sts.html#cco-ccoctl-configuring_cco-mode-sts), can be utilized.
If you prefer not to use `ccoctl`, or your system doesn't support it, the AWS CLI can be an alternative.

The controller pod will wait for the generated credentials secret if `AWSLoadBalancerController` already exists or it can be configured in the `credentials` field of `AWSLoadBalancerController` before its creation.

#### [Extract and prepare the `ccoctl` binary](https://docs.openshift.com/container-platform/4.11/authentication/managing_cloud_provider_credentials/cco-mode-sts.html#cco-ccoctl-configuring_cco-mode-sts)
#### Use `CredentialsRequest` created by the operator

#### Extract required `CredentialsRequests`
1. Extract and prepare the `ccoctl` binary as described in [Configuring the Cloud Credential Operator utility](https://docs.openshift.com/container-platform/4.13/authentication/managing_cloud_provider_credentials/cco-mode-sts.html#cco-ccoctl-configuring_cco-mode-sts).

1. For `AWSLoadBalancerController` CR the **aws-load-balancer-operator** creates a `CredentialsRequest` named `aws-load-balancer-controller-cluster` in the `openshift-cloud-credential-operator` namespace. Extract and save the created `CredentialsRequest` in a directory:
2. For `AWSLoadBalancerController` CR the **aws-load-balancer-operator** creates a `CredentialsRequest` named `aws-load-balancer-controller-cluster` in the `openshift-cloud-credential-operator` namespace. Extract and save the created `CredentialsRequest` in a directory:

```bash
oc get credentialsrequest -n openshift-cloud-credential-operator \
aws-load-balancer-controller-cluster -o yaml > <path-to-credrequests-dir>/cr.yaml
```
Note: currently `AWSLoadBalancerController` CR can only be named `cluster`

2. Use the `ccoctl` tool to process all `CredentialsRequest` objects from the credrequests directory:
3. Use the `ccoctl` tool to process all `CredentialsRequest` objects from the credrequests directory:

```bash
ccoctl aws create-iam-roles \
Expand All @@ -46,13 +59,13 @@ secret is created and available before spawning the **aws-load-balancer-controll
of secrets in a **manifests** directory that is required
by the **aws-load-balancer-controller**.

3. Apply the secrets to your cluster:
4. Apply the secrets to your cluster:

```bash
ls manifests/*-credentials.yaml | xargs -I{} oc apply -f {}
```

4. Verify that the corresponding **aws-load-balancer-controller** pod was created:
5. Verify that the corresponding **aws-load-balancer-controller** pod was created:

```bash
oc -n aws-load-balancer-operator get pods
Expand All @@ -61,12 +74,19 @@ secret is created and available before spawning the **aws-load-balancer-controll
aws-load-balancer-operator-controller-manager-b55ff68cc-85jzg 2/2 Running 0 3h26m
```

### Use predefined `CredentialsRequest`
In case the provisioning of the credentials secret should not be done by the **cloud-credential-operator**, the secret needs to be explicitly referenced in `AWSLoadBalancerController` CR, see [credentials.name field description](./tutorial.md#credentialsname).
However, this credentials secret needs to reference a role with all the policies needed by the controller. For this purpose a dedicated controller's `CredentialsRequest` is maintained in [hack/controller](../hack/controller/) directory of this repository.
Its contents are identical to the ones requested from the **cloud-credential-operator**.
#### Use a Predefined Secret
In some cases, the provisioning of the credentials secret cannot be done by the **cloud-credential-operator**, e.g. ROSA user clusters are forbidden to create `CredentialsRequest`.
Instead, the secret can be explicitly referenced in the `AWSLoadBalancerController` CR, see [credentials.name field description](./tutorial.md#credentialsname).
The credentials secret needs to reference a role with all the policies needed by the controller.
There are two options for creating the credentials secret. Use Option 1 with `ccoctl`, or Option 2 with the AWS CLI.

##### Option 1. Using `ccoctl`
The dedicated controller's `CredentialsRequest` is maintained in [hack/controller](../hack/controller/) directory of this repository.
Its contents are identical to the ones requested by **aws-load-balancer-operator** from the **cloud-credential-operator**.
1. Use the `ccoctl` tool to process the controller's `CredentialsRequest` object:
1. [Extract and prepare the `ccoctl` binary](https://docs.openshift.com/container-platform/4.13/authentication/managing_cloud_provider_credentials/cco-mode-sts.html#cco-ccoctl-configuring_cco-mode-sts)
2. Use the `ccoctl` tool to process the controller's `CredentialsRequest` object:

```bash
ccoctl aws create-iam-roles \
Expand All @@ -81,13 +101,13 @@ Its contents are identical to the ones requested from the **cloud-credential-ope
of secrets in a **manifests** directory that is required
by the **aws-load-balancer-controller**.

2. Apply the secrets to your cluster:
3. Apply the secrets to your cluster:

```bash
ls manifests/*-credentials.yaml | xargs -I{} oc apply -f {}
```

3. Verify that the controller's credentials secret is created:
4. Verify that the controller's credentials secret is created:
```bash
oc -n aws-load-balancer-operator get secret aws-load-balancer-controller-manual-cluster -o json | jq -r '.data.credentials' | base64 -d
Expand All @@ -96,3 +116,59 @@ Its contents are identical to the ones requested from the **cloud-credential-ope
role_arn = arn:aws:iam::999999999999:role/aws-load-balancer-operator-aws-load-balancer-controller
web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token
```
##### Option 2. Using the AWS CLI
1. Generate a trusted policy file using your identity provider (e.g. OpenID Connect):
```bash
IDP="<my-oidc-provider-name>"
IDP_ARN="arn:aws:iam::<my-aws-account>:oidc-provider/${IDP}"
cat <<EOF > albo-controller-trusted-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "${IDP_ARN}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${IDP}:sub": "system:serviceaccount:aws-load-balancer-operator:aws-load-balancer-controller-cluster"
}
}
}
]
}
EOF
```
2. Create and verify the role with the generated trusted policy:
```bash
aws iam create-role --role-name albo-controller --assume-role-policy-document file://albo-controller-trusted-policy.json
CONTROLLER_ROLE_ARN=$(aws iam get-role --role-name albo-controller | \grep '^ROLE' | \grep -Po 'arn:aws:iam[0-9a-z/:\-_]+')
echo $CONTROLLER_ROLE_ARN
```
3. Attach the controller's permission policy to the role:
```bash
curl -o albo-controller-permission-policy.json https://raw.githubusercontent.com/openshift/aws-load-balancer-operator/main/assets/iam-policy.json
aws iam put-role-policy --role-name albo-controller --policy-name perms-policy-albo-controller --policy-document file://albo-controller-permission-policy.json
```

4. Generate the operator's aws credentials:
```bash
cat <<EOF > albo-controller-aws-credentials.cfg
[default]
sts_regional_endpoints = regional
role_arn = ${CONTROLLER_ROLE_ARN}
web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token
EOF
```
**Note**: verify the format of the credentials file. Examples can be found in [OCP documentation](https://docs.openshift.com/container-platform/4.13/authentication/managing_cloud_provider_credentials/cco-mode-sts.html#sts-mode-about_cco-mode-sts).
5. Create the operator's credentials secret with the generated aws credentials:
```bash
oc -n aws-load-balancer-operator create secret generic aws-load-balancer-controller-cluster --from-file=credentials=albo-controller-aws-credentials.cfg
```
92 changes: 90 additions & 2 deletions docs/prerequisites.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
# Pre-Requisites

## CredentialsRequest
- [AWS credentials](#aws-credentials)
- [For non-STS clusters](#for-non-sts-clusters)
- [For STS clusters](#for-sts-clusters)
- [Option 1. Using ccoctl](#option-1-using-ccoctl)
- [Option 2. Using AWS CLI](#option-2-using-the-aws-cli)
- [VPC and Subnets](#vpc-and-subnets)
- [VPC](#vpc)
- [Subnets](#subnets)
- [Public subnets](#public-subnets)
- [Private subnets](#private-subnets)

## AWS credentials
Additional AWS credentials are needed for the operator to be successfully installed. This is needed to interact with subnets and VPCs.

### For non-STS clusters
Expand All @@ -27,9 +38,19 @@ Additional AWS credentials are needed for the operator to be successfully instal
### For STS clusters
1. [Extract and prepare the `ccoctl` binary](https://docs.openshift.com/container-platform/4.11/authentication/managing_cloud_provider_credentials/cco-mode-sts.html#cco-ccoctl-configuring_cco-mode-sts)
There are two options for creating the credentials secret:
- Using a pre-defined `CredentialsRequest`.
- Using pre-defined AWS manifests.
For handling `CredentialsRequests`, the cloud credential operator utility, [ccoctl](https://docs.openshift.com/container-platform/latest/authentication/managing_cloud_provider_credentials/cco-mode-sts.html#cco-ccoctl-configuring_cco-mode-sts), can be utilized.
If you prefer not to use `ccoctl`, or your system doesn't support it, the AWS CLI can be an alternative.
#### Option 1. Using `ccoctl`
1. [Extract and prepare the `ccoctl` binary](https://docs.openshift.com/container-platform/4.13/authentication/managing_cloud_provider_credentials/cco-mode-sts.html#cco-ccoctl-configuring_cco-mode-sts)
2. Create AWS Load Balancer Operator's namespace:
```bash
oc create namespace aws-load-balancer-operator
```
Expand Down Expand Up @@ -66,6 +87,73 @@ Additional AWS credentials are needed for the operator to be successfully instal
web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token
```
#### Option 2. Using the AWS CLI
1. Create AWS Load Balancer Operator's namespace:
```bash
oc create namespace aws-load-balancer-operator
```
2. Generate a trusted policy file using your identity provider (e.g. OpenID Connect):
```bash
IDP="<my-oidc-provider-name>"
IDP_ARN="arn:aws:iam::<my-aws-account>:oidc-provider/${IDP}"
cat <<EOF > albo-operator-trusted-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "${IDP_ARN}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${IDP}:sub": "system:serviceaccount:aws-load-balancer-operator:aws-load-balancer-operator-controller-manager"
}
}
}
]
}
EOF
```
3. Create and verify the role with the generated trusted policy:
```bash
aws iam create-role --role-name albo-operator --assume-role-policy-document file://albo-operator-trusted-policy.json
OPERATOR_ROLE_ARN=$(aws iam get-role --role-name albo-operator | \grep '^ROLE' | \grep -Po 'arn:aws:iam[0-9a-z/:\-_]+')
echo $OPERATOR_ROLE_ARN
```
4. Attach the operator's permission policy to the role:
```bash
curl -o albo-operator-permission-policy.json https://raw.githubusercontent.com/alebedev87/aws-load-balancer-operator/aws-cli-commands-for-sts/hack/operator-permission-policy.json
aws iam put-role-policy --role-name albo-operator --policy-name perms-policy-albo-operator --policy-document file://albo-operator-permission-policy.json
```
5. Generate the operator's aws credentials:
```bash
cat <<EOF > albo-operator-aws-credentials.cfg
[default]
sts_regional_endpoints = regional
role_arn = ${OPERATOR_ROLE_ARN}
web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token
EOF
```
**Note**: mind the format of the credentials file, examples can be found in [OCP documentation](https://docs.openshift.com/container-platform/4.13/authentication/managing_cloud_provider_credentials/cco-mode-sts.html#sts-mode-about_cco-mode-sts).
6. Create the operator's credentials secret with the generated aws credentials:
```bash
oc -n aws-load-balancer-operator create secret generic aws-load-balancer-operator --from-file=credentials=albo-operator-aws-credentials.cfg
```
## VPC and Subnets
The **aws-load-balancer-operator** requires specific tags on some AWS
Expand Down
18 changes: 18 additions & 0 deletions hack/generate-iam-from-credrequest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#! /bin/bash

set -euo pipefail

CR_FILE="${1:-operator-credentials-request.yaml}"
POLICY_FILE="${2:-operator-permission-policy.json}"
YQ_BIN="go run github.com/mikefarah/yq/v4"

STATEMENTS=$(${YQ_BIN} -o=json .spec.providerSpec.statementEntries "${CR_FILE}")

cat <<EOF > "${POLICY_FILE}"
{
"Version": "2012-10-17",
"Statement": ${STATEMENTS}
}
EOF
${YQ_BIN} -i -o=json "${POLICY_FILE}"
sed -i -e 's/action/Action/g' -e 's/effect/Effect/g' -e 's/resource/Resource/g' "${POLICY_FILE}"
27 changes: 27 additions & 0 deletions hack/operator-permission-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:DescribeSubnets"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:subnet/*"
},
{
"Action": [
"ec2:DescribeVpcs"
],
"Effect": "Allow",
"Resource": "*"
}
]
}

0 comments on commit 791e160

Please sign in to comment.