Build AWS Resources Platform using Crossplane | S3| VPC| EC2
Tags: crossplane, platform, aws, helm
Published: 2024-01-30 03:16:12

**Crossplane** is an open source Kubernetes extension that transforms your Kubernetes cluster into a universal control plane.

**Crossplane** is to manage resources ,services and it allows you to create resources/services/infrastructure as you would in something like Terraform, except instead, you’d use a Kubernetes Manifest.


- CNCF Project
- Build Platform with Kubernetes Resources
- Multi Cloud Control plane
- It’s an alternative IAC tooling to Terraform , AWS CDK /Bicep or Pulumi


## Advantages of Crossplane:

- Drift Detection
- No External Code Management
- Infrastructure as a code


**For example**, you can use the Crossplane Operator within Kubernetes to create an S3 bucket in AWS from Kubernetes. Literally, you can write a Kubernetes Manifest that creates an AWS S3 bucket.


There are many providers, list here: https://marketplace.upbound.io/providers


**Prerequisites** 

- An actively supported Kubernetes version
- Helm version v3.2.0 or later

Configuration:
Add the Crossplane repository with the helm repo add command.

```
helm repo add crossplane-stable https://charts.crossplane.io/stable
```

Update the local Helm chart cache with helm repo update.

```
helm repo update
```

```
helm search repo crossplane
```

View the changes Crossplane makes to your cluster with the 

> helm install --dry-run --debug options

Install the Crossplane Helm chart 

```
helm install crossplane \
--namespace crossplane-system \
--create-namespace \
--version 1.13.2
crossplane-stable/crossplane 
```

```
kubectl get pods -n crossplane-system

```
check providers has been installed in the cluster

```
kubectl get crds  | grep crossplane.io
```

## AWS
Once Crossplane is installed, you can start going through the actual configuration of using it.

To use Crossplane, regardless of which Provider you’re using (Azure, AWS, GCP, etc.), you’ll need two key components:

## The Provider itself:

Credentials for authentication with AWS provider,We need to create a kubernetes secret containing the AWS Credentials.

```
$cat ~/.aws/credentials
aws_access_key_id = AKIAW
aws_secret_access_key = 1sPsc8HUWtY3xlg
```

```
$kubectl create secret \
generic aws-secret \
-n crossplane-system \
--from-file=creds=./aws-credentials.txt
```
In order to install the ProviderConfig you need to first install the Provider.

```
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws-s3
spec:
  package: xpkg.upbound.io/upbound/provider-aws-s3:v0.47.1
```

Once the secret and provider is created refer that secret in ProviderConfigs

```
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: creds
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: aws-secret
      key: creds
```

To ensure that the provider was installed properly, run the following command.

```
kubectl get providers
kubectl get pods -n crossplane-system
kubectl get crds  | grep aws.upbound.io
```



You’re now ready to use Crossplane. Below is a configuration to create an **S3 bucket**.

```
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
  name: ravindra-crossplane
spec:
  forProvider:
    region: us-east-1
  providerConfigRef:
    name: default
```

Below is a configuration to create **VPC**.
```
apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
metadata:
  name: dev-vpc
spec:
  forProvider:
    region: us-east-1
    cidrBlock: 10.100.0.0/16
    enableDnsSupport: true
    enableDnsHostnames: true
    tags:
      ManagedBy: Crossplane
      Name: dev-vpc

---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: EIP
metadata:
  name: dev-nat
spec:
  forProvider:
    region: us-east-1
    vpc: true
    tags:
      Name: dev-nat
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: NATGateway
metadata:
  name: dev-nat
spec:
  forProvider:
    connectivityType: public
    region: us-east-1
    allocationIdRef:
      name: dev-nat
    subnetIdSelector:
      matchLabels:
        name: dev-public-us-east-1a
    tags:
      Name: dev-nat
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: InternetGateway
metadata:
  name: dev-igw
spec:
  forProvider:
    region: us-east-1
    tags:
      Name: dev-igw
      ManagedBy: Crossplane
    vpcIdRef:
      name: dev-vpc
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
metadata:
  name: dev-private-us-east-1a
  labels:
    name: dev-private-us-east-1a
spec:
  forProvider:
    availabilityZone: us-east-1a
    cidrBlock: 10.100.1.0/24
    region: us-east-1
    tags:
      Name: dev-private-us-east-1a
      ManagedBy: Crossplane
    vpcIdRef:
      name: dev-vpc
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
metadata:
  name: dev-private-us-east-1b
  labels:
    name: dev-private-us-east-1b
spec:
  forProvider:
    availabilityZone: us-east-1b
    cidrBlock: 10.100.2.0/24
    region: us-east-1
    tags:
      Name: dev-private-us-east-1b
      ManagedBy: Crossplane
    vpcIdRef:
      name: dev-vpc
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
metadata:
  name: dev-public-us-east-1a
  labels:
    name: dev-public-us-east-1a
spec:
  forProvider:
    availabilityZone: us-east-1a
    cidrBlock: 10.100.3.0/24
    region: us-east-1
    tags:
      Name: dev-public-us-east-1a
      ManagedBy: Crossplane 
    vpcIdRef:
      name: dev-vpc
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
metadata:
  name: dev-public-us-east-1b
  labels:
    name: dev-public-us-east-1b
spec:
  forProvider:
    availabilityZone: us-east-1b
    cidrBlock: 10.100.4.0/24
    region: us-east-1
    tags:
      Name: dev-public-us-east-1b
      ManagedBy: Crossplane 
    vpcIdRef:
      name: dev-vpc
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: RouteTable
metadata:
  name: dev-private
spec:
  forProvider:
    region: us-east-1
    tags:
      Name: dev-private
    vpcIdRef:
      name: dev-vpc
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Route
metadata:
  name: dev-private
spec:
  forProvider:
    destinationCidrBlock: 0.0.0.0/0
    natGatewayIdRef:
      name: dev-nat
    region: us-east-1
    routeTableIdRef:
      name: dev-private
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: RouteTable
metadata:
  name: dev-public
spec:
  forProvider:
    region: us-east-1
    tags:
      Name: dev-public
    vpcIdRef:
      name: dev-vpc
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Route
metadata:
  name: dev-public
spec:
  forProvider:
    destinationCidrBlock: 0.0.0.0/0
    gatewayIdRef:
      name: dev-igw
    region: us-east-1
    routeTableIdRef:
      name: dev-public
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: RouteTableAssociation
metadata:
  name: dev-private-us-east-1a
spec:
  forProvider:
    region: us-east-1
    routeTableIdRef:
      name: dev-private
    subnetIdRef:
      name: dev-private-us-east-1a
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: RouteTableAssociation
metadata:
  name: dev-private-us-east-1b
spec:
  forProvider:
    region: us-east-1
    routeTableIdRef:
      name: dev-private
    subnetIdRef:
      name: dev-private-us-east-1b
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: RouteTableAssociation
metadata:
  name: dev-public-us-east-1a
spec:
  forProvider:
    region: us-east-1
    routeTableIdRef:
      name: dev-public
    subnetIdRef:
      name: dev-public-us-east-1a
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: RouteTableAssociation
metadata:
  name: dev-public-us-east-1b
spec:
  forProvider:
    region: us-east-1
    routeTableIdRef:
      name: dev-public
    subnetIdRef:
      name: dev-public-us-east-1b
```

Below is a configuration to create an **EC2**.
```
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Instance
metadata:
  name: crossplane-instance
spec:
  forProvider:
    region: us-east-1
    ami: ami-0a3c3a20c09d6f377
    instanceType: t2.micro
    keyName: crossplane-key
    subnetId: subnet-08653b62be4f06e9d
    associatePublicIpAddress: true
    vpcSecurityGroupIdRefs:
      - name: crossplane-sg
    tags:
      ManagedBy: Crossplane
      Name: dev-instance
  providerConfigRef:
    name: default

---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: SecurityGroup
metadata:
  name: crossplane-sg
spec:
  forProvider:
    description: Allow TLS inbound traffic
    name: allow_rules
    region: us-east-1
    tags:
      Name: allow_rules
      ManagedBy: Crossplane
    vpcIdRef:
      name: dev-vpc
---

apiVersion: ec2.aws.upbound.io/v1beta1
kind: SecurityGroupRule
metadata:
  name: crossplane-sg
spec:
  forProvider:
    cidrBlocks:
      - 0.0.0.0/0
    fromPort: 0
    protocol: tcp
    region: us-east-1
    securityGroupIdRef:
      name: crossplane-sg
    toPort: 65535
    type: ingress    
```
If you prefer a video tutorial to help guide you through the process of Build AWS Resources Platform using Crossplane
{% youtube Ojs9h8rkC5Q %}

References:

- GIT Link: [https://github.com/ravindrasinghh/build-aws-platform-using-crossplane/tree/master]