Hi! Here is the complete code below. Forgive me that i don’t know how to compose type. 
Some "*tag.Value"s are nil.
package main
import (
"database/sql"
"fmt"
"log"
"reflect"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
_ "github.com/go-sql-driver/mysql" //_ stands for only importing init func in the package
)
var region = "us-west-2"
type ec2Resources struct {
Name *string
Env *string
Service *string
Role *string
InstanceType *string
}
func writeInstances() {
//Create a new session
sess := session.Must(session.NewSession())
svc := ec2.New(sess)
//Describe all instances
result, err := svc.DescribeInstances(nil)
if err != nil {
panic(err)
}
var data ec2Resources
for idx, _ := range result.Reservations {
for _, inst := range result.Reservations[idx].Instances {
data.InstanceType = inst.InstanceType
//List instance tags
for _, tag := range inst.Tags {
v := "Null"
if tag.Value == nil {
fmt.Printf("%s is nil", *tag.Key)
continue
}
if reflect.ValueOf(&tag.Value).IsNil() {
fmt.Println("Nil")
}
if tag.Value != nil {
v = *tag.Value
}
k := *tag.Key
fmt.Println(k, v)
switch k {
case "Name":
data.Name = &v
case "Environment":
data.Env = &v
case "Service":
data.Service = &v
case "Role":
data.Role = &v
}
// fmt.Println(reflect.TypeOf(*tag))
// if *tag.Key == "Name" {
// //fmt.Printf("Env is %s\n", *tag.Value)
// if tag.Value != nil {
// data.Name = tag.Value
// fmt.Println("Name")
// } else {
// *data.Name = "Null"
// }
// } else if *tag.Key == "Environment" {
// if tag.Value != nil {
// data.Env = tag.Value
// fmt.Println("Env")
// } else {
// *data.Env = "Null"
// }
// } else if *tag.Key == "Service" {
// if tag.Value != nil {
// data.Service = tag.Value
// } else {
// panic("errrrrrror")
// *data.Service = "Null"
// }
// } else if *tag.Key == "Role" {
// if tag.Value != nil {
// data.Role = tag.Value
// } else {
// *data.Role = "Null"
// fmt.Println("Role")
// panic("NULL")
// }
// }
}
//Update first, if not exist, then try to insert.
fmt.Println(reflect.TypeOf(*data.Role))
sql := fmt.Sprintf(
"UPDATE ec2 SET Environment = %s, Service = %s, Role = %s, InstanceType = %s",
*data.Env,
*data.Service,
*data.Role,
*data.InstanceType,
)
fmt.Println("update finish")
log.Println("sql:", sql)
result, err := db.Exec(sql)
if err != nil {
log.Println("Exec failed:", err, ";SQL:", sql)
return
}
//c is number of affected rows.
c, err := result.RowsAffected()
if err != nil {
log.Println("Rows affected failed:", err)
return
}
//If affected rows num is 0, then INSERT.
if c == 0 {
sql := fmt.Sprintf(
"INSERT INTO ec2(Name, Environment, Service, Role, InstanceType) VALUES ('%s', '%s', '%s', '%s', '%s')",
*data.Name,
*data.Env,
*data.Service,
*data.Role,
*data.InstanceType,
)
log.Println("Not exist, try to insert.")
_, err := db.Exec(sql)
if err != nil {
log.Println("Exec Failed", err, ";SQL:", sql)
}
}
}
}
}
var db *sql.DB
var err error
func connectDatabase() {
db, err = sql.Open("mysql", "jizheng/password@xxx/mysql")
//log.Fatal will terminate process immediately but panic will do until defer func finish.
if err != nil {
log.Fatal("Database connected failed!")
}
fmt.Println("Database connected.")
}
func main() {
connectDatabase()
writeInstances()
db.Close()
}